已经为反应还原剂在动作,减速器或组件中提取了检查数据吗?

时间:2017-04-11 16:51:40

标签: reactjs redux react-redux

相当简单的问题,但我是Redux的新手,所以有点不确定最佳做法。如果我想检查是否已经提取了某些数据,我应该将该检查放在action,reducer,component或其他地方(例如,中间件)吗?

我希望每次从组件请求数据时都不必重复使用相同的检查,从而获得最大的灵活性。

以下是我的设置的简化版本...提前感谢!

// Action
export const fetchData = () => (dispatch) => {
  const data = { ...someData };
  dispatch({ type: 'FETCH_DATA_FULFILLED', data: data });
};

// Reducer
export const DataReducer = (state = {
  fetching: false,
  fetched: false,
  data: [],
}, action) => {
  switch (action.type) {
    case 'ADD': {
      return { ...state, data: [...state.data, action.data] };
    }
    case 'FETCH_DATA_START': {
      return { ...state, fetching: true };
    }
    case 'FETCH_DATA_FULFILLED': {
      return { ...state, fetching: false, fetched: true, data: action.data };
    }
    default: {
      return state;
    }
  }
};

// React component
export class Display extends React.Component {
  componentWillMount () {
    if (!this.props.data.fetched && !this.props.data.fetching) {
      this.props.dispatch(fetchData());
    }
  }
  render () {
    // ...
  }
}

2 个答案:

答案 0 :(得分:2)

如果您将这种条件逻辑放在reducers中,它会闻到,因为reducers应该没有副作用。

我建议将该逻辑保留在fetchData方法中。至少这是我把它放在我的应用程序中的地方。如果在Component内提取数据,则无需检查。不仅您的Component会更简单,而且如果您决定更改提取条件,也可以让您在将来最大限度地减少更改。如果数据过时则重新获取。

如果您在不同的抓取操作中看到您正在重复相同的逻辑(即检查是否未获取,然后获取),则可能值得将其置于某种middleware,但我怀疑值得的。也许,引入fetch action factory将是更清洁的解决方案。

答案 1 :(得分:1)

几点

操作告诉您的应用程序发生了什么。 操作回答了已发生的问题,但没有说明应用程序状态在响应中的变化

reducer是一个纯函数,它接受前一个状态和一个动作,并返回下一个状态,就是它所做的全部。减速器不应该做的事情是例如执行API调用等副作用

我认为一个最佳实践以及改变我的代码反应方式的东西就是理解Container Components。目前,您的组件负责获取数据和呈现数据。这是“好的”,但你错过了React的主要优点。组合性。如果在组件中添加大量数据逻辑,则错过了在其他位置重用组件的可能性。

小例子,未经测试

//container.js
import Component from 'component.js';
import { fetchData } from './actions';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return {
    data: state.data
  };
}

const mapDispatchToProps = (dispatch) => {
  return {
    fetchData: () => {
      dispatch(fetchData())
        .then((data) => //Do something else
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Component);

//component.js
const RenderComponent = props =>
  <ul>
    {this.props.data.map(e => (
      <li>{e.somethinghere}</li>
    ))}
  </ul>

所以回答你的问题:将数据提取逻辑添加到容器组件中