我最近开始使用react-redux构建我的前端应用程序,但是当我编写组件时,我对道具和状态感到困惑。
例如:
content
,type
changeContent
,changeType
,fetchResult
。fetched_result
。组件的结构:
<Layout>
<Header/>
<SearchContent />
<SearchType />
<SearchButton /> -> call axios to get result
<View />
<Chart />
当前 Layout.js 定义所有功能。
changeContent(e) {
this.setState({"content": e.target.value,});
}
changeType(e) {
this.setState({"type": e.target.value,});
}
fetchResult() {
this.props.dispatch(fetchResultAction(this.state.content, this.state.type)).then(()=>{...});
}
我将所有state
和props
传递给每个组件。
<Header
changeType={this.changeType.bind(this)}
changeContent={this.changeContent.bind(this)}
fetchResult={this.fetchResult.bind(this)}
/>
<SearchContent
changeContent={this.props.changeContent}
/>
<SearchType
changeType={this.props.changeType}
/>
<SearchButton
fetchResult={this.props.fetchResult}
/>
<View
type={this.state.type}
result={this.props.fetched_result}
/>
当然,每个组件都运行良好。但是,所有与代码相关的状态都是用Layout编写的。
在这个简单的例子中,如果我用参数定义 fetchResult就可以了:
//this can be defined in any component
fetchResult(content, type) {
this.props.dispatch(fetchResultAction(content, type).then(()=>{...});
const { fetched_result } = this.props;
//I need to define a new "changeResult" function and "result" state in Layout
this.changeResult(fetched_result); //pass result back to layout state
}
然后我可以在任何具有传递状态的组件中使用此函数。
然而,真正的应用程序有很多组件与复杂的关系。当我将布局功能分成以下组件时,我遇到了很多耦合问题。
例如,fetchResult
使用州searched
。
//this is defined in Layout
fetchResult() {
this.props.dispatch(fetchResultAction(this.state.content, this.state.type).then(()=>{
if(this.state.searched==false){
this.setState({"searched": true});
}
});
}
如果我仍然采取第二种方式,我可能需要定义并将更多状态和更改XXX函数传递给组件。
我希望有人可以在reactjs中给我一些道具/状态的最佳实践。
state
和changeState
,并在每个内部组件中定义相关功能。all state related function
,并将内部组件作为props传递。 答案 0 :(得分:2)
通过查看代码,它看起来是正确的。根据我的经验,我建议你可以遵循一些模式,以便在react-redux中构建复杂的应用程序。
以下几条建议您可以关注您的申请。
<强> 1。始终创建Dummy组件和Container组件。
虚拟组件:非常可重用的组件例如。文本框可以是虚拟组件。在你的情况下,搜索按钮,标题,可以是一个虚拟组件。这些组件应该是纯粹的,不应包含任何操作逻辑。这些组件始终将数据作为容器组件的道具获取。在这个组件中我们应该使用回调处理程序例如 textbox将有onchange方法将值传递给容器组件。
容器组件:可以包含多个虚拟组件和另一个容器的组件。所有Action逻辑都将放在容器组件中。的例如即可。表单,在你的情况下它的布局页面(我建议你应该创建单独的容器组件并将该容器组件放在布局中)。
注意:容器组件应直接与redux状态绑定。
容器组件应使用action creator传递API调用所需的值或更新redux状态。
2. 动作创建者:始终将动作创建者保留在单独的文件中。这些action方法应该负责ajax调用,redux状态管理。 的例如即可。用户表单应具有单独的操作创建者文件,该文件将具有(表单的“添加”,“编辑”,“删除”方法)。它还可以帮助您维护复杂的场景以及容器将是干净的。
注意:如果操作方法非常可重用,那么您可以将该方法保留在某个常见位置。
建议:你应该在动作创建者中保留所有重要的逻辑。 (它将帮助您在容器内部具有最小逻辑,并且您的容器将是干净的。)
<强>例如即可。如果你想保存用户表单并在保存时想要显示微调器,在保存之后你想要显示一些消息然后进行一些其他操作,那么你可以将所有操作放在一个函数中
export function Save() {
return function (dispatch, getStore) {
dispatch({ type: START_SPINNER, data: true })
axiosRequest(dispatch, req1).then(function (data) {
dispatch({ type: STOP_SPINNER, data: true })
dispatch({ type: SHOW_SUCESSMESAGE, data: 'SAVED SUCCESSFULLY' });
dispatch({type: CLOSE_FORM, data: {close:true})
})
}
}
<强> 4 即可。如果你需要在组件内部传递多个道具,请使用{... props} ES6方式传递它,而不是手动传递每个属性。
<强> 5 即可。你的减速机应该非常平面。只有它应该包含redux状态的更新逻辑。
<强> 6 即可。使用redux状态而不是反应状态来维护全局数据(可以跨多页使用的那些数据)。
您可以在此处找到更多信息
http://redux.js.org/docs/basics/ExampleTodoList.html
https://www.codementor.io/reactjs/tutorial/intro-to-react-redux-pros
如果您要探索,您可以在多个库中找到编码风格。