While working on a React Native application with a persistent Redux store (in TypeScript) I ran into the following problem:
I built a Thunk that queries an API, this API sends back a set of question data in a fetch. This fetch works fine, but when trying to save any data to the Redux Store using extraReducers
I get errors.
My code looks like this:
First I call a dispatch on the Thunk in my page:
questionpage.tsx-stuff- useEffect(() => { console.log('dispatching fetch') dispatch(fetchQuestions()) }, []);-render stuff-
The actual thunk looks like this and does a fetch to my API:
export const fetchQuestions = createAsyncThunk('questions/fetchquestions', async () =>{ let headers = new Headers(); headers.append('Authorization', 'Basic '+ Base64.btoa(email +":" + password)) const response = await fetch(api +"/api/questions", { headers: headers, method: 'GET' }) const stuff = await response.json(); console.log(stuff) return stuff;})
Then:
questionSlice extraReducers: (builder) => { builder.addCase(fetchQuestions.pending, (state, action) => { state.status = 'loading' // < when I comment this the console.log works console.log('pending') }), builder.addCase(fetchQuestions.fulfilled, (state, action) => { state.status = 'succeeded' // Add any fetched posts to the array state.questions = state.questions.concat(action.payload) // < comment this, console.log works console.log('fulfilled') }) builder.addCase(fetchQuestions.rejected, (state, action) => { state.status = 'failed' // < when I comment this the console.log works state.error = action.error.message // < when I comment this the console.log works console.log('rejected') }) }
As you see above: In my reducer I use the extraReducers
to catch the different results this Thunk can produce. This works, but only when I modify nothing in the state. If I try to save anything to the state I get the following error:
[Unhandled promise rejection: Error: [Immer] Immer only supports setting array indices and the 'length' property]
This error occurs at all times, it occurs when I modify state.status
, which is a String, not an Array, it also occurs when I modify state.error
and state.questions
The last one is an array, but the other two are not.
I looked at a lot of other questions but couldn't find this specific scenario anywhere and am fairly lost on how to proceed.
Update:My problem stems from Immer
. If I understand the documentation correctly Immer
should allow me to do updates of objects in the Redux state, but I cannot get it to work:
export const questionSlice = createSlice({ name: 'question', initialState, reducers: { save: (state, action) => { state.questions.push(action.payload) < this action works } }, extraReducers: (builder) => { builder.addCase(fetchQuestions.fulfilled, (state, action) => { state.questions.push(action.payload) < this action errors })