Optimizing State With Selective Updates

Provide a snippet that selectively updates only the relevant parts of the state in response to a createAsyncThunk action, avoiding unnecessary re-renders.
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

// An example async function that fetches data from an API
const fetchData = async (userId) => {
    const response = await fetch(`/api/data/${userId}`);
    const data = await response.json();
    return data;

// createAsyncThunk creation
export const fetchDataThunk = createAsyncThunk(
    async (userId, { rejectWithValue }) => {
        try {
            const data = await fetchData(userId);
            return data;
        } catch (error) {
            return rejectWithValue(;

// Slice with selective updates
export const dataSlice = createSlice({
    name: 'data',
    initialState: { 
        entities: {}, 
        loading: 'idle', 
        error: null 
    reducers: {},
    extraReducers: (builder) => {
            .addCase(fetchDataThunk.pending, (state) => {
                state.loading = 'pending';
            .addCase(fetchDataThunk.fulfilled, (state, action) => {
                // Update only the necessary part of the state
                state.entities[action.meta.arg] = action.payload;
                state.loading = 'idle';
                state.error = null;
            .addCase(fetchDataThunk.rejected, (state, action) => {
                state.loading = 'idle';
                state.error = action.payload;

export default dataSlice.reducer;
This snippet defines an async thunk for fetching data and a slice that selectively updates the state. The state consists of a loading flag, an error message, and a map of entities. The extraReducers property is used to handle actions dispatched by the thunk. When an action is fulfilled, only the entity associated with the request is updated, avoiding wholesale updates of the entire state and preventing unnecessary re-renders.