【问题标题】:React setState: Callback to function of child-componentReact setState:回调子组件的功能
【发布时间】:2021-06-14 15:10:44
【问题描述】:

setState配合回调函数使用时,如何在父组件中调用子组件的函数?

背景资料

一个简单的测验应用程序的三个组成部分:

App.jsx  
-- Questions.jsx  
-- Results.jsx 

要访问结果组件和问题组件中的答案,答案必须保存在应用组件的状态中。

要修改应用组件的状态,每次用户回答问题时,我都需要调用一个从应用组件向下传递到问题组件的函数。设置好app组件的State后,应该会显示下一个问题。因此,应该调用问题组件中的函数nextQuestion()。通常,我只会写setState({results: results}, nextQuestion()),但由于nextQuestion() 是问题组件而不是应用程序组件的功能,所以这不起作用。

我该如何解决这个问题?

非常感谢!

在问题组件中:

checkAnswer = (answer) => {

    if (answer !== this.state.solution) {

      let s = this.state;
      this.props.saveResult(s.question, s.solution[0], answer);

      //[...]
    }
  };

newQuestion = () => {
    //[...]

    let question = [...this.state.question];
    let solution = [...this.state.solution];

    const task = taskGenerator.taskDirectory[taskId](); //generate new question + solution
    question = task.question;
    solution = task.solution;
    this.setState({ question, solution });
  };

在应用组件中:

saveResult = (question, solution, answer) => {
    let results = cloneDeep(this.state.results)
    results.question = question
    results.solution = solution
    results.answer = answer
    this.setState({ results: results }, newQuestion()); //here is the problem; how do I call the newQuestion function of the child component?
  };

【问题讨论】:

  • 你有一些我可以看的代码示例吗?

标签: javascript reactjs callback setstate


【解决方案1】:

setState配合回调函数使用时,如何在父组件中调用子组件的函数?

简而言之,您不需要 :) 而是将状态 从父级传递给子级。这实际上是您问题的根源:

但是由于 nextQuestion() 是问题组件的函数,而不是应用程序组件的函数,所以这不起作用。

简而言之,作为 React 开发人员,有两个“规则”可以让你的状态在你的应用中去哪里。要理解它们,您必须将您的应用程序视为“树”,顶部有App,下面有所有子组件、孙子组件等...

  1. 状态必须位于或高于需要使用状态的每个组件
  2. 应用树中的状态应尽可能低(同时仍遵循 #1)

看来您正在尝试遵循规则 #2 并保持您的状态低(好)...但是您的应用程序违反了第一条规则:您的状态(nextQuestion 依赖于 this.state.question)您的 @987654324 @ 取决于。该状态比它需要的“更低”(在您的应用树中),并且由于它不在App 级别,App 无法使用它。

这意味着您需要将nextQuestion(以及为其供电的状态)移动到App,以便您在App 中的代码可以访问nextQuestion .然后,您可以将Question 需要的任何数据作为propsApp 传递。

使用这种结构,您的状态(以及像 nextQuestion 这样的相关函数)将尽可能高地生存(即在 App 级别),因此依赖它的所有逻辑都可以访问,并且任何“低级”组件(如Question)都会简单地将状态通过props“向下传递”。

【讨论】:

  • 感谢您的全面回答!!我希望不要进一步“乱扔”应用程序组件(> 250 行)具有更多功能,但似乎我必须这样做。
  • 再一次,你希望“将你的状态保持在树上”(即不要把它全部推到应用程序中)是一个好的和健康的愿望!但是你只需要确保每个组件都可以访问它需要的数据,在这种情况下,应用程序确实需要数据。
【解决方案2】:
class App extends Component {
...
  setAnswers(answers, callback){
     this.setState({results:answers},callback)
  }
  render(){
    return <Questions setAnswers={this.setAnswers}/>
  }
}

class Questions extends Component {

  onSubmit(answers){
     this.props.setAnswers(answers,this.nextQuestion)
  }
}

另一种方法是对 Questions 子组件中的状态变化做出反应,这可能是更好的方法。

【讨论】:

  • 谢谢!如果我正确理解了您的建议,则函数 nextQuestion 将作为参数传递给 parent 函数,并在 setState 成功执行后在那里执行。因此,在 nextQuestion 函数中,我不能再访问和修改问题组件的状态,可以吗?
  • 你可以,如果那是你想要的。您可以将this.state 传递给回调。 this.setState({results: answers}, ()=&gt;callback(this.state)) 然后将在Question 组件中接收修改后的状态。
  • 好吧,没看到!谢谢!
【解决方案3】:

如果我正确理解您的问题,您应该能够将该函数作为道具从父组件传递给子组件。我相信这篇文章也回答了你的问题。 Call child method from parent

干杯!

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 1970-01-01
    • 2022-11-22
    • 2021-04-20
    • 2020-09-02
    • 2021-05-22
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多