Skip to content
Advertisement

An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft

I understand this has been asked before but so far no answers except someone making a syntax mistake. I have verified this against every tutorial I’ve seen online and I can’t find the issue. It seems to be coming from the fullfilled extraReducer

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const KEY = process.env.REACT_APP_API_KEY
const BASE_URL = process.env.REACT_APP_BASE_URL
const GLOBALVIEWS_API = `${BASE_URL}/countrymap`

const initialState = {
  mapdata:{},
  status: 'idle',  //'idle', 'loading', 'succeeded', 'failed'  
  error:null
}

export const fetchMapData = createAsyncThunk(
  'mapdata/fetchMapData', 
  async (id) => { 
    const response = await axios.get(
      GLOBALVIEWS_API,
      {
        headers: {
          'Content-Type': 'application/json',
          'X-API-KEY': KEY,
        },
        params: {
          titleId: id,
        }
      }
    )

    return response.data.Item;
  }
)

const mapSlice = createSlice({
  name: 'mapdata',
  initialState,
  reducers:{
    addMapData: (state, { payload }) => {
      state.mapdata = payload
    }
  },
  extraReducers: {
    [fetchMapData.pending]: () => {
      console.log("Pending");
    },
    [fetchMapData.fulfilled]: (state, { payload }) => {
      state.status = 'succeeded'
      console.log("Succeeded", payload);
      return {...state, mapdata: payload}
    },
    [fetchMapData.rejected]: () => {
      console.log("Rejected");
    },
  }
})

// SELECTORS
export const getMapStatus = (state) => state.mapdata.status;

export const allMapData = (state) => state.mapdata.mapdata;
export const { addMapData } = mapSlice.actions;


export default mapSlice.reducer

In the component, nothing weird, and yes everything is imported

const {id} = useParams();
const dispatch = useDispatch();

const allmapdata = useSelector(allMapData)
const addmapdata = useSelector(addMapData) 
const mapStatus = useSelector(getMapStatus)

useEffect(() => { 
  dispatch(fetchMapData(id))
  
  lazy(setMap(allmapdata)) 
  console.clear()
  console.log("mapdata: ", allmapdata);    
      
}, [id, allmapdata, dispatch])

You can see in my image below that my fetch is successful and I am getting data. So how do I get rid of this error? Thanks in advance.

enter image description here

Advertisement

Answer

This is the issue:

 state.status = 'succeeded'
 console.log("Succeeded", payload);
 return {...state, mapdata: payload}

That is indeed both a “mutation of the existing stateand a “return of a new value”, and that’s exactly what the error is warning you about.

You can change that to:

state.status = 'succeeded'
state.mapdata = action.payload
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement