在ReactJS中从父状态更新子道具
我试图理解如何用不同的“页面”或“视图”构造ReactJS应用程序 我将以下组件作为我的基础应用程序,并且我正在React状态中使用currentState属性在视图中的活动组件之间切换在ReactJS中从父状态更新子道具,reactjs,Reactjs,我试图理解如何用不同的“页面”或“视图”构造ReactJS应用程序 我将以下组件作为我的基础应用程序,并且我正在React状态中使用currentState属性在视图中的活动组件之间切换 class App extends React.Component { constructor(props) { super(props); this.state = {currentState: 'Loading', recipes: []}; thi
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];
}
}
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.state={currentState:'Loading',recipes:[]};
this.appStates={
“加载”:,
“家”:
}
}
数据加载(数据){
这是我的国家({
配方:数据,
当前状态:“主页”
});
}
componentDidMount(){
//从服务器检索菜谱,然后调用dataLoaded的AJAX代码
}
render(){
返回this.appStates[this.state.currentState];
}
}
它执行此任务,但在启动dataLoaded回调时,组件从不接收更新的recipes数组
如何根据应用程序中的更新状态更新道具
还是我处理这整件事的方式不对?我建议做的是将构造函数中的所有组件代码推送到渲染函数内部。react的美妙之处在于,您可以以极低的成本完全重新渲染所有内容。React将完成比较DOM中差异的艰苦工作,并且只重新呈现最小的差异。我建议做的是将构造函数中的所有组件代码推送到呈现函数内部。react的美妙之处在于,您可以以极低的成本完全重新渲染所有内容。React将完成比较DOM差异的艰苦工作,并且只重新呈现最小的差异。只有当组件装载时,才会执行构造函数方法,此时配方为空,并将该空数组传递给AppState。本质上,appStates从不更改。只有当组件装载时,才会执行构造函数方法,此时recipes为空,并将该空数组传递给appStates。本质上,AppState永远不会改变。我认为您的Approach并不是真正的反应,您至少有几个概念可以改进 首先,我肯定会使用React.js实现页面/组件之间的复杂导航。自己实现它更复杂,也更容易出错。react路由器将允许您轻松地将组件分配到不同的路由 其次,我认为您几乎不应该直接将内容存储在上下文
this
中。基本上是因为它会导致像您这样的错误:没有意识到appStates
根本没有改变。React的状态是存储应用程序状态的一个很好的工具(有时必须用其他工具(如Redux)替换/补充)
在将组件中应该呈现的内容存储在状态中的情况下,您可能应该使用构造函数中初始化的状态中的简单标志来补充react router功能,这些标志允许您知道在呈现函数中应该返回什么
下面的示例演示了如何通过使用just React的状态,告诉组件在加载和加载之间动态更改其视图。当然,您可以在componentDidMount中调用AJAX并更改状态以在加载完成时停止加载,而不是使用按钮,从而重新创建一个非常类似的行为
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.state={loading:true};
this.stopLoading=this.stopLoading.bind(this);
}
停止加载(){
这是我的国家({
加载:false,
});
}
render(){
让视图=加载完成;
如果(!this.state.loading){
视图=已加载;
}
返回{view};
}
}
ReactDOM.render(
,
document.getElementById('容器')
);代码>
我认为您的aproach并不是真正的反应,您至少有几个概念可以改进
首先,我肯定会使用React.js实现页面/组件之间的复杂导航。自己实现它更复杂,也更容易出错。react路由器将允许您轻松地将组件分配到不同的路由
其次,我认为您几乎不应该直接将内容存储在上下文this
中。基本上是因为它会导致像您这样的错误:没有意识到appStates
根本没有改变。React的状态是存储应用程序状态的一个很好的工具(有时必须用其他工具(如Redux)替换/补充)
在将组件中应该呈现的内容存储在状态中的情况下,您可能应该使用构造函数中初始化的状态中的简单标志来补充react router功能,这些标志允许您知道在呈现函数中应该返回什么
下面的示例演示了如何通过使用just React的状态,告诉组件在加载和加载之间动态更改其视图。当然,您可以在componentDidMount中调用AJAX并更改状态以在加载完成时停止加载,而不是使用按钮,从而重新创建一个非常类似的行为
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.state={loading:true};
this.stopLoading=this.stopLoading.bind(this);
}
停止加载(){
这是我的国家({
加载:false,
});
}
render(){
让视图=加载完成;
如果(!this.state.loading){
视图=已加载;
}
返回{view};
}
}
ReactDOM.render(
,
document.getElementById('容器')
);代码>
我同意@Ezra Chang的观点。我认为代码可以调整,只利用州和to pas
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];
}
}