ReactJS:道具和国家的最佳实践

时间:2017-04-04 11:36:20

标签: javascript reactjs web-component

我最近开始使用react-redux构建我的前端应用程序,但是当我编写组件时,我对道具和状态感到困惑。

例如:

  • 陈述:contenttype
  • 功能:changeContentchangeTypefetchResult
  • 道具: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(()=>{...});
}

我将所有stateprops传递给每个组件。

<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中给我一些道具/状态的最佳实践。

  1. 在最外层组件中定义statechangeState,并在每个内部组件中定义相关功能。
  2. 在最外面的组件中定义all state related function,并将内部组件作为props传递。

1 个答案:

答案 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

如果您要探索,您可以在多个库中找到编码风格。