I have a parent component A which will have a child component B. The parent component can have multiple similar child components. I want to process the data of this child component in the parent component hence I pass a functions as props to the child component. Now whenever a change is made in the child component I want to re-render all the components from the parent. I have a state in the parent called componentList which is an array of type object. Each object will have data about one child component. This gives me syntax error and if I change and try something else it gives me undefined value for componentList.
export class Parent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
componentList: []
};
this.onClick = this.onClick.bind(this);
this.onDataChange = this.onDataChange.bind(this);
}
public onDataChange(index: number) {
return function(data: Data) {
this.setState({
this.state.componentList[index].name = data.name;
});
};
}
In child component I am updating the name onChange as below:
interface Props {
name?: string;
age?: number;
onDataChange: (data: Data) => void;
}
export class Child extends React.Component<Props> {
constructor(props: Props) {
super(props);
this.state = {};
this.onNameChange = this.onNameChange.bind(this);
}
public onNameChange(event) {
this.props.onDataChange({
name: event.target.value,
age: this.props.age
});
}
Getting error: "TypeError: Cannot read property 'componentList' of undefined"
Are you doing binding of onDataChange function before sending to the props?
export class parentClass extends Component{
constructor(props){
super(props);
this.onDataChange=this.onDataChange.bind(this);
}
}*/
If not, this keyword in onDataChange invocation points to the wrong context
also replace
this.setState({
this.state.componentList[index].name = data.name;
});
with something like
this.setState({componentList:newComponentList});
As my comment seemed to help you, I've decided to post an answer. Your onDataChange
function is returning another function to be invoked by the child.
public onDataChange(index: number) {
return function(data: Data) { // A function gets returned
this.setState({
this.state.componentList[index].name = data.name;
});
};
}
and inside the child you are binding the reference of the this
keyword to the this
keyword of the child:
this.onDataChange=this.onDataChange.bind(this);
which is generally not wrong, but you want to update the state on the parent, therefore you need a reference to the parent this.
This can be easily achieved by simply changing the return "value" of your onDataChange
function.
public onDataChange(index: number) {
// An arrow function always set the this reference to where it's declared correctly,
// therefore this inside the function will reference the parent this.
return (data: Data) => {
this.setState({
this.state.componentList[index].name = data.name;
});
};
}
What's also obsolete then is: this.onDataChange = this.onDataChange.bind(this);
inside your parent constructor.
It might be helpful to read up on this topic over at MDN - Arrow functions .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.