# Redux Toolkit

```
yarn add react-redux @reduxjs/toolkit
```

includes the Redux core, as well as other key packages like(Redux Thunk and Reselect, immer) and helper functions

## Configure Store

* A [`configureStore()` function](https://redux-toolkit.js.org/api/configureStore) with simplified configuration options. It can automatically combine your slice reducers, adds whatever Redux middleware you supply, includes `redux-thunk` by default, and enables use of the Redux DevTools Extension.

```jsx
const store = configureStore({
  reducer: counter
})
```

## Create Slice

* A [`createSlice()` function](https://redux-toolkit.js.org/api/createSlice) that accepts a set of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types. Default(unknown action type) returns current.&#x20;
  * Mutations of state will auto create a new object on change as needed

```jsx
import { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({
  name: "counter",
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
    //called when dispatch type counter/addTodo
    addTodo(state, action) {
      const { id, text } = action.payload;
      state.push({ id, text, completed: false });
      //allowed to mutuate because function wrapped with produce from Immer library
    },
  },
});

export const { increment, decrement, addTodo } = todosSlice.actions;

export default todosSlice.reducer;
```

### Old Helpers but unneeded b/c create Slice

* A [`createReducer()` utility](https://redux-toolkit.js.org/api/createReducer) that lets you supply a lookup table of action types to case reducer functions, rather than writing switch statements. In addition, it automatically uses the [`immer` library](https://github.com/mweststrate/immer) to let you write simpler immutable updates with normal mutative code, like `state.todos[3].completed = true`.

```jsx
//OLD
function counter(state = 0, action) {
  switch (action.type) {
    case increment.type:
      return state + 1
    case decrement.type:
      return state - 1
    default:
      return state
  }
}

//NEW
const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')

const counter = createReducer(0, {
  [increment.type]: state => state + 1,
  [decrement.type]: state => state - 1
})
```

* A [`createAction()` utility](https://redux-toolkit.js.org/api/createAction) that returns an action creator function for the given action type string. The function itself has `toString()` defined, so that it can be used in place of the type constant.

```jsx
const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')

//With payload generation helper, must return object with payload
export const addTodo = createAction('ADD_TODO', text => {
  return {
    payload: { id: nextTodoId++, text }
  }
})

const counter = createReducer(0, {
  [increment]: state => state + 1,
  [decrement]: state => state - 1
})

const store = configureStore({
  reducer: counter
})

document.getElementById('increment').addEventListener('click', () => {
  store.dispatch(increment())
})
```

* However, we can take advantage of `createAsyncThunk` to clean up the above code, and to create those three actions automatically:

  ```javascript
  const usersSlice = createSlice({
    name: 'users',
    initialState: { entities: [], loading: 'idle' },
    reducers: {
      // standard reducer logic, with auto-generated action types per reducer
    },
    extraReducers: {
      // Add reducers for additional action types here, and handle loading state as needed
      [fetchUserById.fulfilled]: (state, action) => {
      // Add user to the state array
        state.entities.push(action.payload)
    }
    }
  })

  const getUsers = createAsyncThunk("users/getUsers", () => {
    return fetch("/api/users/")
      .then(response => {
        if (!response.ok) throw Error(response.statusText);
        return response.json();
      })
      .then(json => json);
  });
  ```

  What `createAsyncThunk` does here, is to **automatically create an action creator for each Promise state**. For example if we name our async thunk "users/getUsers", it generates:

  * **pending**: "users/getUsers/pending"
  * **rejected**: "users/getUsers/rejected"
  * **fulfilled**: "users/getUsers/fulfilled"


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openai.gitbook.io/code-cheatsheets/react/state_management/redux/redux_toolkit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
