如何将基于内部状态的React应用转换为基于Redux?

时间:2018-07-19 12:39:57

标签: javascript reactjs redux

我编写了基于内部状态的React应用。它使用“ axios”库从Web API提取数据。它看起来如下:

class OrdersTable extends React.Component {
  constructor() {
    super();

    this.state = {
      orders: [],
      ...
  }

  componentDidMount() {
    setTimeout(() => {
      axios.get("http://localhost:1234/api/orders").then(response => {
        this.setState({
          orders: response.data,
        });
      });
    }, 2000);
  }

  render () {
    return (
      <div className="content-wrapper">
        <div className="content-left">
           <BootstrapTable keyField='id' data={this.state.orders} columns={this.state.columns}
             rowStyle = {this.state.rowStyle} rowEvents={this.rowEvents}
             caption={<CaptionOrders title="Orders" />} noDataIndication={<NoData />} {...this.props} />
           <Legend />
        </div>
      </div>
    )
  }
}

我想将其转换为使用Redux而不是内部状态。我从以下内容开始:

index.js:

const store = createStore(reducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

动作:

import { LOAD_DATA } from '../constants/action-types';

export const loadData = orders => ({
  type: LOAD_DATA,
  payload: orders
})

减速器:

export default initialState = {
  orders: []
};

const reducer = (state = initialState, action) => {
  switch(action.type) {
    case LOAD_DATA:
      return {
        ...state, orders: action.payload };
    default:
      return state;
  }
}

容器:

const mapStateToProps = (state) => ({
  orders: state.orders
})

const mapDispatchToProps = (dispatch) => ({
  // Should "axios" call be here and if so, how should look like?
});

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

修饰语成分:

How can I use the orders state from Redux in OrdersTable component?

2 个答案:

答案 0 :(得分:1)

Redux中的HTTP调用被认为是副作用。它们不是Redux本身的一部分,它只是一个状态管理库。因此,除了Redux之外,您还必须使用另一个库,其中最简单的是redux-thunk

使用redux-thunk,您可以定义副作用,它实际上是一个可以分派多次的函数。例如:

import { LOAD_DATA } from '../constants/action-types';

export const getOrders = () => async (dispatch) => {
    try {
        const response = await axios.get("http://localhost:1234/api/orders");
        dispatch(loadData(response.data))
    } catch (e) {
        /* ... */
    }
}

export const loadData = orders => ({
type: LOAD_DATA,
payload: orders
})

答案 1 :(得分:1)

Jayce444是正确的,您应该使用redux-thunk。我认为这是规范的方法。

查看此答案:https://stackoverflow.com/a/34458710/8896573

如果您想保留此基本知识,请忽略mapDispatchToProps(仍做mapStateToProps),并在axios响应中只需调用this.props.dispatch(loadData(订单))

然后由于mapStateToProps的结构,您的“订单”在您的组件中以this.props.orders的形式提供:)