如何通过将功能作为道具传递给子代来更新父代的状态

时间:2019-11-12 00:25:31

标签: javascript reactjs typescript

我有一个父组件A,它将有一个子组件B。该父组件可以有多个类似的子组件。我想在父组件中处理此子组件的数据,因此我将一个函数作为道具传递给了子组件。现在,每当子组件发生更改时,我都希望从父组件重新渲染所有组件。我在父中有一个叫做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;
    });
  };
}

在子组件中,我正在更新名称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
  });
}

获取错误:“ TypeError:无法读取未定义的属性'componentList'”

2 个答案:

答案 0 :(得分:1)

在发送给道具之前,您是否在绑定onDataChange函数?

export class parentClass extends Component{
    constructor(props){
        super(props);
        this.onDataChange=this.onDataChange.bind(this);
    }
}*/

如果不是,则onDataChange调用中的 this 关键字指向错误的上下文

也替换

this.setState({
    this.state.componentList[index].name = data.name;
});

类似

this.setState({componentList:newComponentList});

答案 1 :(得分:1)

由于我的评论似乎对您有所帮助,因此我决定发布答案。您的onDataChange函数正在返回另一个要由孩子调用的函数。

public onDataChange(index: number) {
  return function(data: Data) { // A function gets returned
    this.setState({
      this.state.componentList[index].name = data.name;
    });
  };
}

在子对象内部,您将this关键字的引用绑定到子对象的this关键字:

this.onDataChange=this.onDataChange.bind(this);

这通常没错,但是您想更新父级的状态,因此您需要对此父级进行引用。

只需更改onDataChange函数的返回“值”即可轻松实现。

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;
    });
  };
}

然后也过时的是:父构造函数中的this.onDataChange = this.onDataChange.bind(this);

MDN - Arrow functions上仔细阅读本主题可能会有所帮助。