How do I pass parent state to its child components? - reactjs

I am new in React ES6 and I think I am modifying the state in a wrong way. My code is like this when I set state on parent component:
class App extends React.Component {
constuctor(props) {
super(props);
this.state = {name:"helloworld"};
}
render() {
return(
<ChildComponent parentObj={this} /> // parentObj for parent context as props on child components
);
}
}
My problem is in other child components, I have to do it repeatitively, is there another way of doing it? I have no problem with React.createClass, but I want to code in es6 so i have this problem.

If you wanna pass the state {name:"helloworld"} do it like that:
class App extends React.Component {
constuctor(props) {
super(props);
this.state = {name:"helloworld"};
}
render() {
return(
<ChildComponent {...this.state} />
);
}
}
and in the child component you can do:
<Text>{this.props.name}</Text>
But If you want to pass the props of the component to it's child:
class App extends React.Component {
constuctor(props) {
super(props);
this.state = {name:"helloworld"};
}
render() {
return(
<ChildComponent {...this.props} />
);
}
}
and in the child component you can do:
<Text>{this.props.stuff}</Text>//place stuff by any property name in props
Now if you want to update the state of parent component from the child component you will need to pass a function to the child component:
class App extends React.Component {
constuctor(props) {
super(props);
this.state = {name:"helloworld"};
}
update(name){
this.setState({name:name})// or with es6 this.setState({name})
}
render() {
return(
<ChildComponent {...this.props, update: this.update.bind(this)} />
);
}
}
and then in child component you can use this : this.props.update('new name')
UPDATE
use more es6 and removed constructor
class App extends React.Component {
state = {name:"helloworld"};
// es6 function, will be bind with adding .bind(this)
update = name => {
this.setState({name:name})// or with es6 this.setState({name})
}
render() {
// notice that we removed .bind(this) from the update
return(
//send multiple methods using ','
<ChildComponent {...this.props, update = this.update} />
);
}
}

if you want to send the whole state :
return( <ChildComponent {...this.state} /> );
But this is likely a bad idea :)
edit: in your scenario, this sends a 'name' property to child component with value 'helloworld'

Related

How to access the parent props from the child component?

How to access Parent's props in the Child's tag and function sayhello?
(I can access siblings and children without passing props as an argument but not the parent)____________________________________________
And (away from this example) If this refers to Parent, how to access Child's props?
And if this refers to Child as an html tag, is there a function to convert the result into the react component class? (not reassigning this as the class to a new variable () => instead of function())
Child:
class Child extends Parent{
constructor(props){
super(props);
}
render() {
return (
<p>{Parent.props.hello}</p> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<button onClick={sayhello.bind(this)}></button> // <<<<<<<<<<<<<<<<<<<<<<<<
);
}
}
Parent:
class Parent extends React.Component{
constructor(props){
super(props);
}
render() {
<>
<Child/>
</>
}
}
sayhello:
function sayhello(){
console.log(Parent.props); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
If you bind the function in component, you can refer to this.props:
class Child extends React.Component {
render() {
return (
<>
<button onClick={sayhello.bind(this)}>Click</button>
</>
);
}
}
class Parent extends React.Component {
render() {
return (
<>
<Child someProp="hello" />
</>
);
}
}
function sayhello() {
console.log(this.props);
}

Props are empty on passing them to child class based components while filled when using functional component

It seems that props are not being passed to child component when my child component is a class based component. This is my parent component:
class ScreeningsList extends React.Component{
state = {screenings: [] };
componentDidMount = async () => {
const response = await apis.getAllScreenings();
this.setState({screenings: response.data});
}
render(){
return (
<div>
<ScrTest screeningsList = {this.state.screenings}/>
</div>
)
}
}
And here is my child component:
class ScrTest extends React.Component{
render(){
return (
<div className="screeningsContainer">
<h2>Title: {this.props.screeningsList._id}</h2>
</div>
)
}
}
Here I tried just to display id of the screening. The value in props did not exist. There were no props at all.
However when I use functional component and use the arrow function:
const ScreeningsToRender = props => {
...
}
I can access props by using props.screeningsList and use every value that is inside that prop. Rendering the component is succesfull and I can see the list of all the screenings. What should I do to recieve props properly in my child component?
You need a constructor in the child component:
class ScrTest extends React.Component{
constructor(props){
super(props);
}
render(){
return (
<div className="screeningsContainer">
<h2>Title: {this.props.screeningsList._id}</h2>
</div>
)
}
}
"When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor".
Source: https://reactjs.org/docs/react-component.html#constructor

React: How can you access the class name of a parent component from a child without passing it down as props?

Say you have a parent component:
// ParentComponent
class ParentComponent extends React.Component {
render() {
return(
<ChildComponent/>
)
}
}
From inside the child component, is there a way to access the class name of the parent component without passing this down as props?
// ChildComponent
class ChildComponent extends React.Component {
// ?????
getParentComponentName() {
return this.??? // Should return "ParentComponent"
}
render() {
return(
<div/>
)
}
}
I'd prefer to be able to access this without passing it down as props. Thank you!
You need to access ReactInternalFiber like
class Child extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' }
}
getParentName = () =>{
this.setState({ name: this._reactInternalFiber._debugOwner.type.name })
}
render() {
return (
<div>
<h1>Name: {this.state.name}</h1>
<button onClick={this.getParentName}>Get Parent Name</button>
</div>
)
}
}

Accessing/Changing Parents State from Child Class using props (React)

I am trying to set state of the parent class with the child. But having trouble figuring out how to do this. I've abstracted away anything I deemed irrelevant to the question at hand. The issue is that I am
Class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
}
coolMethod(n){
this.setState({foo: n})
}
render{
return(
<Child coolmethod={this.coolMethod} />
)
}
}
Class Child extends Component {
constructor(props){
super(props)
}
componentDidMount(){
let that = this;
videojs('my-player', options, function onPlayerReady() {
this.on('end',()=>{
that.props.coolMethod(<whatever string returns as a result of
this method>)
})
})
}
render{
return(
// irrelevant stuff to this question
)
}
}
Currently this code gives me "type error: this.setState is not a function"
If you want more info on videojs: http://videojs.com/ (though this is irrelevant to the question by itself, other than the fact that I reference it in my videojs call in componentDidMount of the child)
I assume the 2nd class is Class Child extends Component .... You need to bind this.coolMethod in your Parent constructor first.
Class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
this.coolMethod = this.coolMethod.bind(this);
}
coolMethod(n){
this.setState({foo: n})
}
render{
return(
<Child coolmethod={this.coolMethod} />
)
}
}
Try this, tested working on my side, found two issues in the code
Javascript is case sensitive coolmethod is passed in to the Child, but you are trying to access coolMethod.
You need this > this.coolMethod = this.props.coolMethod.bind(this); in the constructor to inherit the setState function from the Parent, otherwise, this inside the coolMethod will be undefined.
import React, { Component } from 'react';
export default class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
}
coolMethod(n){
this.setState({foo: n})
}
render(){
return(
<Child coolMethod={this.coolMethod} />
)
}
}
class Child extends Component {
constructor(props){
super(props)
this.coolMethod = this.props.coolMethod.bind(this);
}
render(){
return(
<button onClick={() => this.coolMethod("aabbcc")}>1</button>
)
}
}

Changing the state of a parent component using a function in the child compontent

I'm new to React, and I decided to build something simple like a Calculator to practice it's basics. However I have some trouble to understand the logic behind the information flow, and either there is a way for a child component to do the logic and update the parent in a natural way.
For example this is the basic structure of my calculator:
class Calculator extends React.Component {
render() {
return (
<div className="calculator-main">
<Screen numberOnScreen={this.state.numberOnScreen}/>
<NumberButton number={7} />
<NumberButton number={8} />
<NumberButton number={9} />
<OperatorButton operator="plus" view="-"/>
....
</div>
)
}
}
class Screen extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="screen">{new Intl.NumberFormat().format(this.props.numberOnScreen)}</div>
);
}
};
class NumberButton extends React.Component {
constructor(props) {
super(props);
}
render() {
const zeroClass = this.props.number === 0 ? " zero" : "";
return (
<button type="button" className={"number" + zeroClass}>{this.props.number}</button>
);
}
};
So I know that:
I can create the functions inside Calculator and pass it as a prop to
the buttons components, and call it onClick. (But it just feel weird).
Create an event listener in the Calculator compontent, create the
function inside the button component and pass the value via the event
trigger; (But it feels artificial).
Use some kind of global store?
But is there no natural react way to do this?
Thanks!
I think you want to know about React component communication. Here, I have implemented Child to Parent communication.
In this case Parent's state and state change method passes to child component through props. Then child can change parent's state use this method.
React Component Communication
//Parent component
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
content: 'Initial Content'
}
this.changeContent = this.changeContent.bind(this);
}
changeContent(event){
this.setState({
content: event.target.value
})
}
render(){
let { content } = this.state;
return <div>
<Child content={content} changeContent={this.changeContent}/>
<h1>{content}</h1>
</div>
}
}
// Child component
class Child extends React.Component{
constructor(props){
super(props);
}
render(){
let { content, changeContent } = this.props;
return <input value={content} onChange={changeContent}/>
}
}

Resources