【问题标题】:Redux Toolkit: have two consecutive dispatch and the latter is dependent upon the formerRedux Toolkit:有两个连续的dispatch,后者依赖于前者
【发布时间】:2020-12-20 06:21:10
【问题描述】:

我有一个名为getRole 的操作和一个名为getPoliciesFrom 的操作。 getRole 返回角色,getPoliciesFrom 返回附加到该角色的策略列表。然后我需要调度这些动作来支持一个特性。

我在useEffect 中发送getRole 并使用useSelector 获取role 作为状态

const role = useSelector((state: RootState) => state.settings.role);

//...

useEffect(() => {
  dispatch(getRole());
}, [dispatch]);

现在为了获得政策,我想到了两个选择:要么我添加一个条件检查以查看 role 是否为空,当它不是 null 时,发送 getPoliciesFrom 并传入 @987654333 @ 作为它的论点。所以看起来像这样:

const role = useSelector((state: RootState) => state.settings.role);

useEffect(() => {
  dispatch(getRole());
  if(role) {
    dispatch(getPoliciesFrom(role));
  }
}, [dispatch]);

或者我使用第一次调度返回的承诺,并在承诺解决时将第二次调度附加到then。看起来像这样

useEffect(() => {
  dispatch(getRole()).then(result => dispatch(getPoliciesFrom(result))
}, [dispatch]);

两者似乎都在工作。但是对于第二种方法,我的 ts 编译器对我大喊大叫 then 我附在调度上,说

“AsyncThunkAction'。

但我确实从getRole 返回了结果。这是它的代码

export const getRole = createAsyncThunk(
  "settings/getRole",

  async () => {
    let response: GetServiceRoleForAccountResponse;

    try {
      response = await api.getServiceRoleForAccount().promise();
    } catch (error) {
      if (
        error.statusCode === notAssociatedStatusCode &&
        error.message === notAssociatedErrorMessage
      ) {
        return { role: null };
      }

      throw error;
    }

    return { role: response.role };
  }
);

我也不确定如何正确键入从承诺中返回的result

最重要的是,这里哪种方法更好?

【问题讨论】:

  • 确保在 getRole 中返回结果:const getRole = arg => dispatch => {return async.then((role)=>{dispatch(someAction);return role;})}

标签: reactjs typescript redux redux-toolkit


【解决方案1】:

您需要在 getRole 中返回结果,这是一个 thunk 操作的工作示例,该操作返回一个解析为一个值的 Promise:

const { Provider, useDispatch, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;

const initialState = {
  num: 0,
};
//action types
const OK = 'OK';
//action creators
const ok = (num) => (dispatch) =>
  //returning a promise
  new Promise((resolve) =>
    setTimeout(() => {
      dispatch({
        type: OK,
        payload: num,
      });
      //resolving the promise to a value
      resolve(num);
    }, 2000)
  );

const reducer = (state, { type, payload }) => {
  if (type === OK) {
    return { num: payload };
  }
  return state;
};
//selectors
const selectNum = (state) => state.num;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware(
      ({ dispatch, getState }) => (next) => (action) =>
        typeof action === 'function'
          ? action(dispatch, getState)
          : next(action)
    )
  )
);
const App = () => {
  const num = useSelector(selectNum);
  const dispatch = useDispatch();
  React.useEffect(() => {
    dispatch(ok(88)).then((num) =>
      console.log('num here is:', num)
    );
  }, [dispatch]);
  console.log('num in render:', num);
  return String(num);
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>

【讨论】:

  • 您好,感谢您的回复。我实际上确实从getRole 返回了结果。我已经更新了我的答案,添加了 getRole 的外观的 sn-p。顺便说一句,您认为哪种方法更好?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多