简体   繁体   English

如何通过将 function 作为道具传递给其子级来更新父级的 state

[英]How to update state of parent by passing a function as props to its children

I have a parent component A which will have a child component B. The parent component can have multiple similar child components.我有一个父组件 A,它将有一个子组件 B。父组件可以有多个相似的子组件。 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.我在父组件中有一个 state,它是一个 object 类型的数组。 Each object will have data about one child component.每个 object 都将包含一个子组件的数据。 This gives me syntax error and if I change and try something else it gives me undefined value for componentList.这给了我语法错误,如果我更改并尝试其他方法,它会给我未定义的 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:在子组件中,我正在更新名称 onChange,如下所示:

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"出现错误:“TypeError:无法读取未定义的属性‘componentList’”

Are you doing binding of onDataChange function before sending to the props?在发送到道具之前,您是否正在绑定 onDataChange function?

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如果不是,onDataChange 调用中的这个关键字指向错误的上下文

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.您的onDataChange function 正在返回另一个 function 以供孩子调用。

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关键字的引用绑定到孩子的this关键字:

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.这通常没有错,但是您想更新父级上的 state,因此您需要对父级 this 的引用。

This can be easily achieved by simply changing the return "value" of your onDataChange function.这可以通过简单地更改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);那么也过时的是: 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 .MDN-Arrow 函数中阅读此主题可能会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM