Answer a question

Environment

  1. Redux-Toolkit
  2. React
  3. Typescript
  4. Grpahql

Background

I'm using redux and redux-toolkit for local state management. I read the redux-toolkit docs. I found that we can dispatch thunk action with createAsyncThunk() function in redux-toolkit. This function automatically dispatch pending, fulfilled, rejectedaction.

When my async work would fail, thunk dispatch rejected action with action.error as a SerializedError type. And we can customize the result of error with rejectWithValue() function. Like this.

const fetchAdminPassword = createAsyncThunk('adminPassword/fetch', async (_, { rejectWithValue }) => {
  try {
    const result = await client.query<{adminPassword: string}>({ query: FETCH_ADMIN_PASSWORD });
    const { data: { adminPassword } } = result;
    return adminPassword;
  } catch (err) {
    rejectWithValue("Error!!");
  }
});



builder.addCase(fetchAdminPassword.rejected, (state, action) => {
  state.fetchError = action.payload;
  state.fetchPending = false;
})

Problem

The type of action.payload is unknown.

How to chanage this to string?

Answers

Two things: At this point, you still cannot know if this rejection was caused by an unknown "throw" or a return rejectWithValue, so even if you were to correctly type your asyncThunk, action.payload would end up as string | undefined and you would need to use check for payload to not be undefined before continuing.

That aside, you'll need to provide a generic here as described here in the docs:

const fetchAdminPassword = createAsyncThunk<
  {adminPassword: string},
  void,
  {
    rejectValue: string
  }
>('adminPassword/fetch', async (_, { rejectWithValue }) => {
  try {
    const result = await client.query<{adminPassword: string}>({ query: FETCH_ADMIN_PASSWORD });
    const { data: { adminPassword } } = result;
    return adminPassword;
  } catch (err) {
    rejectWithValue("Error!!");
  }
});
Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐