Redux 传奇 - 错误绑定 - 将错误绑定到本地状态的适当方法

Redux saga - error binding - appropriate way to bind error to local state

我们有一个使用 redux-saga 的 ReactJS 应用程序。 在 redux-saga 中,我们执行所有数据抓取(http webrequests)。 此外:我们使用 React hooks。

场景:

我们有一个按钮可以向 redux 发送一个动作。 Redux-saga 处理此操作并触发网络请求。

现在,此网络请求失败(例如服务器已关闭)。

我们现在要做的是改变按钮的文字。 所以实际上,我们想回到动作被调度的“作用域”。

问题:

从 redux-saga 回到按钮的合适方法是什么?

我找到了这个:

https://github.com/ricardocanelas/redux-saga-promise-example

这是否适合在 2021 年与挂钩一起使用?

您发布的那个例子听起来很费解。使用 redux-sagas 处理错误可能相对简单。我们将考虑应用程序的 3 个部分 - UI、商店和 actions/saga 链。

UI:

const SomeUIThing = () => {

  const callError = useSelector(state => state.somewhere.error);
  const dispatch = useDispatch();

  return (
    <button onClick={
      dispatch({
        type: "API_CALL_REQUEST"
      })
    }>
      {callError ? 'There was an error' : 'Click Me!'}
    </button>
  )
}

您可以看到 UI 正在从存储中读取。单击时,它将向商店发送 API_CALL_REQUEST 操作。如果商店中记录了错误,它将有条件地呈现文本按钮,这听起来就像你想要的那样。

商店

您需要一些操作和缩减程序才能在商店中创建或清除错误。所以最初的商店可能是这样的:

const initialState = {
  somewhere: {
    error: undefined,
    data: undefined
  }
}

function reducer(state = initialState, action){
  switch(action.type){
    case "API_CALL_SUCCESS":
      return {
        ...state,
        somewhere: {
          ...state.somewhere,
          data: action.payload
        }
      }
    case "API_CALL_FAILURE":
      return {
        ...state,
        somewhere: {
          ...state.somewhere,
          error: action.payload
        }
      }
    case "CLEAR":
      return {
        ...state,
        somewhere: initialState.somewhere
      }
    default:
      return state;
  }
}

现在您的 reducer 和您的 store 可以处理一些基本的 api 呼叫响应,包括失败和成功。现在让 sagas 处理 api 调用逻辑流

传奇

function* handleApiCall(){
  try {

    // Make your api call:
    const response = yield call(fetch, "your/api/route");

    // If it succeeds, put the response data in the store
    yield put({ type: "API_CALL_SUCCESS", payload: response });

  } catch (e) {

    // If there are any failures, put them in the store as an error
    yield put({ type: "API_CALL_ERROR", payload: e })

  }
}

function* watchHandleApiCall(){
  yield takeEvery("API_CALL_REQUEST", handleApiCall)
}

最后一部分是处理 api 调用的地方。当您单击 UI 中的按钮时,watchHandleApiCall 会侦听从按钮单击中调度的 API_CALL_REQUEST。然后它触发 handleApiCall saga,它发出调用。如果调用成功,则会从存储中触发成功操作。如果它失败了,或者如果有任何错误,一个错误操作会被触发到商店。 UI 然后可以从存储中读取任何错误值并做出相应的反应。

如您所见,使用 try/catch 块,处理 sagas 中的错误可以非常简单,只要您已将商店设置为保存错误。