在componentDidMount上调度一个动作(react / redux)

时间:2017-05-03 15:45:20

标签: reactjs redux react-redux

我是反应/减少的新相对论。因为我想问一个(也许是一个哲学的)问题。

可以在反应组件componentDidMount上发送一个动作(例如触发api调用)吗?

如果没有,我应该为何以及在何处发出行动?

如果是,那么没有其他问题? :)

4 个答案:

答案 0 :(得分:10)

是的,在componentDidMount()上调度操作是可以的,甚至是推荐的事情,因为它不会减慢初始UI渲染速度。

由于函数在组件最初呈现后运行,请记住,在组件呈现的时刻和从api调用接收数据的那一刻之间可能会有一段时间。

答案 1 :(得分:4)

是的,你应该肯定使用componentDidMount钩子。

典型的用例可能是:

  • 组件出现在屏幕上,例如表格
  • 触发服务器请求以获取数据
  • 显示旋转器/装载器覆盖组件
  • 数据回来了
  • 微调器被删除,数据显示在表格中。

我知道它有点长,但我一直在研究这类问题,所以我想我会分享以下模式;)

当组件安装时,将触发获取数据操作。应用程序状态中的'isFetching'值确定是否显示微调器(我认为我使用'advanced-loader'或某些此类库)

export default class MyComponent extends React.Component {

  componentDidMount() {
    AppDispatcher.dispatch({
      type: ActionTypes.FETCH_DATA,
    });
  }

  render() {
    let isFetching = this.props.my.application.path.isFetching;
    return (
      <Loader show={isFetching} message={'loading'}>
        <div>
          My Component
        </div>
      </Loader>
    );
  }
}

然后在商店中FETCH_DATA触发请求:

class AppStore extends ReduceStore {

  //......

  reduce(state, action) {

    let imState = Immutable.fromJS(state);

    switch (action.type) {

      //......

      case ActionTypes.FETCH_DATA:
        doGetRequest('/url_to_service');
        break;

      //......
    }
    return imState.toJS();
  }
}

请求看起来像这样:

function doGetRequest(endpoint, params = {}) {

  //request is some kind of AJAX library. In my case 'superagent'
  request.get(endpoint)
    .set('Accept','application/json')
    .query(params)
    .end(
      (err, res) => {
        if (res && res.ok) {
          receiveData(endpoint, "SUCCESS", res);
        } else {
          receiveData(endpoint, "FAIL");
    }});
}

完成后,它会发出另一个动作。

function receiveData(endpoint, state, responseData) {
  AppDispatcher.dispatch(
    {
      type: ActionTypes.SERVER_RESPONSE,
      endpoint: endpoint,
      state: state,
      payload: responseData
    }
  );
}

回到商店,捕获第二个动作并将isFetching标志设置为false,然后处理应用程序数据。

  reduce(state, action) {

    let imState = Immutable.fromJS(state);

    switch (action.type) {

      //......


      case ActionTypes.SERVER_RESPONSE: {

        imState = imState.setIn(['my','application','path', 'isFetching'], false)

        if (action.state == "SUCCESS") {
            //do something with the action.response data (via state update)
        }else if (action.state == "FAIL") {
            //maybe show an error message (via state update)
        }
        break;
      }
    }
    return imState.toJS();
  }
}

....所以这个典型的用例使用两个'actions',第一个动作是从 componentDidMount 方法触发的,第二个动作是在请求完成后触发的。

希望这种模式有助于:)

答案 2 :(得分:1)

根据官方的React文档,componentDidMount正好是这样做的地方:

  

componentDidMount()在组件出现后立即调用   安装。需要DOM节点的初始化应该放在这里。 如果你   需要从远程端点加载数据,这是一个好地方   实例化网络请求。

- Official React Documentation for componentDidMount()

答案 3 :(得分:0)

当使用路由时,另一种推荐的方式来分派动作将是routes-method“onEnter”。这是为了使组件不依赖于动作(或api-calls)。

我个人认为两种方法(componentDidMount与onEnter)都可以。由程序员选择哪种解决方案最适合他的应用程序。