【问题标题】:How to update state of parent by passing a function as props to its children如何通过将函数作为道具传递给其子级来更新父级的状态
【发布时间】:2019-11-12 00:25:31
【问题描述】:

我有一个父组件 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: Cannot read property 'componentList' of undefined”

【问题讨论】:

  • 您正在绑定孩子内部的 this 引用。然后指向子状态。通过删除绑定,您可以尝试:将 return function(data: Data) { 替换为 return (data: Data) =&gt; { 并重试:)
  • 是的,这行得通。谢谢!

标签: javascript reactjs typescript


【解决方案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);

这通常是没有错的,但是你想更新父级上的状态,因此你需要一个对父级 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 上阅读此主题可能会有所帮助。

【讨论】:

    【解决方案2】:

    在发送到 props 之前,你是否在绑定 onDataChange 函数?

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

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

    也替换

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

    类似的东西

    this.setState({componentList:newComponentList});
    

    【讨论】:

    • 我正在绑定它。我已经更新了问题中的代码以显示这一点。我得到的语法错误是 - 它说“:”的位置是“。”的位置。在 "this.state.componentList[index].name = data.name;"
    • 这将如何 - "this.setState({componentList:newComponentList});"帮助 ?在这种情况下,“newComponentList”应该是什么?
    • newComponentList 是您的 componentList 的更新版本,将 componentList 克隆到其中并进行修改
    猜你喜欢
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多