使用“ useReducer”时如何增加副作用?

时间:2020-03-15 15:03:15

标签: reactjs

我想知道在使用 useReducer 挂钩时需要添加一些副作用的方法。

例如,有一个TODO应用程序:

const initialState = {items: []};

const reducer = (state, action) => {
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        items: [...state.items, action.newItem]
      };

    default:
      throw new Error();
  }
};

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <button onClick={() => dispatch({ type: 'ADD', newItem: 123 })}>
      Add item
    </button>
  );
}

我需要将新项目保存到服务器。问题是:我应该在哪里放置此代码?

(请记住,还原剂应该是纯净的)

1 个答案:

答案 0 :(得分:3)

您可能想使用useEffect钩子。顾名思义,它恰好是每个渲染周期的副作用。一个小的重构,以允许它在组件中。

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState);
  const [newItem, setNewItem] = useState(null);

  useEffect(
    () => {
      // new item! dispatch state update, send to server, and reset newItem
      dispatch({ type: 'ADD', newItem });
      sendNewItemToServer(newItem);
      setNewItem(null);
    },
    [newItem],
  );

  const newItemHandler = item => setNewItem(item);

  return (
    <button onClick={() => newItemHandler(123)}>
      Add item
    </button>
  );
}

当您的应用程序较小时,这很容易,但是随着应用程序规模的增大,您可能需要考虑应用程序级事件处理系统,例如rxjs和redux / epics,redux sagas,redux thunk。这些都依靠redux作为应用程序状态真值的主要来源,并且可以处理对API的异步调用以发送和检索数据。