首页 > 解决方案 > React Hooks,Reducers,Ajax,如何调度新状态

问题描述

我还不明白如何使用异步请求和减速器。我不明白。我正在使用钩子。

我有类似的东西:

const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
        case 'GO':
            myFunctionThatDoesSomethingAsync(params);
            return {
                ...state,
                isChecking: true
            };
}

那么myFunctionThatDoesSomethingAsync是相当标准的,我猜?

const myFunctionThatDoesSomethingAsync = (params) => {
fetch('/endpoint', {
    method: 'POST',
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(
        (result) => {
            if (result.status === 'failed') {
                // this does not work, dispatch is undefined of course
                dispatch({ type: 'FAILED', result: result });
            } else {
                // this does not work, dispatch is undefined of course
                dispatch({ type: 'DONE' });
            }
        }
    );
};

我确定我在这里遗漏了一个概念。我刚刚开始使用 React、Reducers、Hooks 等。

我不知道是否需要以dispatch某种方式传递该方法,但即使我调用myFunctionThatDoesSomethingAsync,该dispatch方法还不存在。

我已经阅读了与async关键字async actions等相关的内容,但不确定它是否适用,这并不清楚。

在这种情况下,我该怎么做才能改变我的状态?(我有相同的代码,但没有 Reducer 并且工作正常,但是因为我可以使用setSomething

标签: javascriptreactjsasynchronousasync-awaitreact-hooks

解决方案


Reducers 应该是纯同步函数。如果您需要进行异步操作(调用 api、setTimeout 等),请在组件主体中调用异步函数,完成后,它应该调度该操作。

例如,我创建了一个asyncInc在一秒钟后分派的函数。reducer 像往常一样在分派时处理动作,并增加状态。

const reducer = (count, step = 1) => count + step;

const App = () => {
  const [count, dispatch] = React.useReducer(reducer, 0);

  const asyncInc = React.useCallback(() => {
    setTimeout(() => dispatch(2), 1000); 
  }, [dispatch]);

  return (
    <div onClick={asyncInc}>{count}</div>
  );
};

ReactDOM.render(
  <App />,
  root
);
div {
  font-size: 2em;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>


推荐阅读