是否可以在Redux reducer内发出REST API请求?

时间:2019-06-08 01:58:27

标签: reactjs react-redux

我有一个名为ItemList的React组件,该组件从API服务器加载项目列表,然后将其呈现为Item组件列表。

每个Item都有一个删除按钮。单击该按钮后,我想向API服务器发送删除该项目的请求,然后重新呈现ItemList

我可以想到的一种方法是将两个API查询都移入reducers,然后在需要时分派操作a)获取所有项目; b)删除一个项目。成功完成这些API操作后,Reducer将更新商店,并且ItemList将重新呈现。

这是一种合理的方法,还是将API调用放入化简器中不是一个好主意吗?

这是到目前为止的代码的简化版本。它尚未使用Redux。我想确保在实现Redux之前我的方法是正确的,因此这是Stack Overflow问题。

ItemList.js

class ItemList extends Component {

  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
    this.componentDidMount = this.componentDidMount.bind(this);
  }

  componentDidMount() {
    const url = 'https://api.example.com/api/v1.0/item';
    fetch(url, {
      method: "get"
    })
    .then(res => res.json())
    .then(response => {
      this.setState({items: response.data});
    });
  }

  render() {
    <div>
      {this.state.items.map((item, index) => (
        <Item key={item.id} item={item} />
      ))}
    </div>
  }
}

Item.js

class Item extends Component {

  deleteClicked() {
    /** 
     *  Is it ok to dispatch a "delete item" action 
     *  from here and then make the actual API call 
     *  in a reducer?
     */
  }

  render() {
    <div>
      <h2>{item.title}</h2>
      <a onClick={this.deleteClicked}>delete item</a>
    </div>
  }
}

1 个答案:

答案 0 :(得分:3)

您几乎解决了您的任务。为了使您的解决方案更加完美,请使用Action creators进行异步调用,并在完成时调度操作。减速器应为pure sync function

例如ItemList组件可以使用此类动作创建者来提取项目

const ExtractItemsAction = () => (dispatch) => {
    distpatch ({type: ITEMS_REQUESTED});
    const url = 'https://api.example.com/api/v1.0/item';
    fetch(url, {
        method: "get"
    })
    .then(res => res.json())
    .then(response => {
        dispatch({type: ITEMS_RECEIVED, items: response.data});
    });
}

减速器将保持纯净

function reducer (state = initalState, action)
{
    switch (action.type) {
        case ITEMS_REQUESTED:
            return { ...state, itemsRequested: true }
        case ITEMS_RECEIVED:
            return { ...state, itemsRequested: false, items: action.items }
        default
            return state;
    }
}

请不要忘记connect组成Redux,并在创建商店时使用Redux-thunk作为中间件。