繁体   English   中英

在ReactJS中从父状态更新子道具

[英]Updating child props from parent state in ReactJS

我试图了解如何构造具有不同“页面”或“视图”的ReactJS应用程序。

我将以下组件作为基本应用程序,并且在React状态下使用currentState属性在视图中处于活动状态的组件之间进行切换。

class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = {currentState: 'Loading', recipes: []};
        this.appStates = {
            'Loading': <Loading/>,
            'Home': <RecipeList recipes={this.state.recipes}/>
        }
    }

    dataLoaded(data) {
        this.setState({
            recipes: data,
            currentState: 'Home'
        });
    }

    componentDidMount() {

        // AJAX Code that retrieves recipes from server and then calls dataLoaded
    }

    render() {
        return this.appStates[this.state.currentState];
    }
}

哪个可以完成工作,但是在触发dataLoaded回调时,组件永远不会收到更新的配方数组。

我该如何根据App中的更新状态来更新道具?

还是我以错误的方式来处理整件事?

我认为您的方法并不是真的很像反应,并且您至少有两个可以改进的概念。

首先,我肯定会使用react-router在React.js中的页面/组件之间实现任何复杂的导航。 自己实施更复杂且容易出错。 react-router允许您轻松地将组件分配给不同的路由。

其次,我认为你应该几乎从不存储在上下文中的东西this直接。 基本上是因为它会导致像您这样的错误:根本没有意识到appStates根本没有改变。 React的状态是一个很棒的工具(有时必须用Redux等其他工具替换/补充)来存储应用程序的状态。

在以状态形式存储应该在Component中呈现的内容的情况下,您可能应该在构造函数中初始化的状态下使用简单标志来补充react-router功能,以使您知道应该在render函数中返回什么。

这是一个示例,显示了如何告诉组件仅使用React的状态在加载和加载之间动态更改其视图。 当然,您可以重新创建一个非常相似的行为,即在componentDidMount中进行AJAX调用,并更改状态以在完成后停止加载,而不是使用按钮。

 class App extends React.Component { constructor(props) { super(props); this.state = {loading: true}; this.stopLoading = this.stopLoading.bind(this); } stopLoading() { this.setState({ loading: false, }); } render() { let view=<div><h1>loading</h1><button onClick={this.stopLoading}>FINISH</button></div>; if(!this.state.loading){ view=<h1>loaded</h1>; } return <div>{view}</div>; } } ReactDOM.render( <App />, document.getElementById('container') ); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="container"></div> 

您的构造方法仅在组件安装时执行,此时配方为空,并将该空数组传递给appStates。 本质上,appStates永远不会改变。

我建议做的是将构造函数中的所有组件代码推送到render函数内部。 反应的好处在于您可以以很少的成本完全重新渲染所有内容。 React将进行比较DOM差异的艰苦工作,并且仅重新呈现最小差异。

我同意@Ezra Chang。 我认为可以仅使用状态和javascript传播函数来调整代码,以将App道具传递给子RecipeList:

class App extends React.Component {

   constructor(props) {
      super(props);
      this.state = {currentState: 'Loading', recipes: [],'Loading': <Loading/>,
        'Home': <RecipeList recipes={this.state.recipes} {...this.props}/>};
   }

   //I assume you want to pass the props of this App component and the data from the back-end as props to RecipeList. 
   dataLoaded = (data) => {
       this.setState({
          recipes: data,
          currentState: 'Home',
          'Loading': <Loading/>,
          'Home': <RecipeList recipes={data} {...this.props}/>
       });
    }

    componentDidMount() {
       // AJAX Code that retrieves recipes from server and then calls dataLoaded
    }

    render() {
       return this.state[this.state.currentState];
    }
 }

暂无
暂无

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

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