我试图了解如何使用不同的"页面来构建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回调时,组件永远不会收到更新的recipes数组。
如何根据应用程序中的更新状态更新其道具?
或者我是以错误的方式接近这一切?
答案 0 :(得分:2)
我认为你的方法并没有真正的反应,你至少有几个可以改进的概念。
首先,我肯定会使用react-router来实现React.js中页面/组件之间的任何复杂导航。自己实现它更复杂,更容易出错。 react-router将允许您轻松地将组件分配到不同的路由。
其次,我认为您几乎不应该直接在上下文this
中存储内容。基本上是因为它会导致像你这样的错误:没有意识到appStates
根本没有改变。 React的状态是一个很好的工具(有时必须用Redux等其他替换/补充)来存储应用程序的状态。
如果在状态中存储应该在Component中呈现的内容,则应该使用构造函数中初始化状态中的简单标志来补充react-router功能,以便您知道在渲染中应该返回什么功能
这是一个示例,显示如何通过仅使用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>
答案 1 :(得分:1)
构造函数方法仅在组件安装时执行,此时配方为空,并将该空数组传递给appStates。从本质上讲,appStates永远不会改变。
答案 2 :(得分:0)
我建议做的是将构造函数中的所有组件代码推送到render函数中。反应的美妙之处在于,您可以以极低的成本完全重新渲染所有内容。 React将努力比较DOM中的差异,只重新渲染最小差异。
答案 3 :(得分:0)
我同意@Ezra Chang。我认为代码可以调整,只使用状态和javascript spread function将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];
}
}