Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Why?

Instead of wasting time on boilerplate, you can get started immediately. The standards followed are the recommended way to write Redux logic for modern JS applications. I found that I am writing less code for core logic & can see this being utilized in any application that needs state management.

Tools:

Set-up:

This example will implement the configureStore(), useSelector(), & useDispatch() tools to run a simple CRUD application. We'll be running off create-react-app for this example.

If you haven’t a react app running yet, run:

npx create-react-app app-name

1.) In the root folder, install react-redux & redux-toolkit:

npm install react-redux @reduxjs/toolkit

2.) Configure the store in a separate store.js file:

import { configureStore } from “@reduxjs/toolkit”;

export const store = configureStore({
    reducer: {},
});

The configureStore() wraps the createStore from Redux & provides simple configuration/defaults. We'll add our reducer later.

3.) From here we want to import our store & pass it as a store in our Provider.

import { store } from './store';
import { Provider } from 'react-redux';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>

  </React.StrictMode>
);

4.) Create a features folder in the root & create a Posts.js file:

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

const initialState = {
    value: [
        {id: '1', title: 'title 1', content: 'test'},
        {id: '2', title: 'title 2', content: 'test'},
    ]
}

export const Posts = createSlice({
    name: 'posts',
    initialState,
    reducers: {
        addPost: (state, action) => {
            state.value.push(action.payload);
        },
        deletePost: (state, action) => {
            state.value = state.value((item) => item.id !== action.payload.id)
        }
    }
})

export const { addPost, deletePost } = Posts.actions;
export default Posts.reducer;

This is the where the Action logic will go:

addPost: (state, action) => {
            state.value.push(action.payload);
        }

state arg is the draft state provided from Immer.

action arg is the object being dispatched.

Importing Actions:

export const { addPost, deletePost } = Posts.actions;

Importing Reducers:

export default Posts.reducer;

5.) Import & add the Post reducer to our store:

import { configureStore, createStore } from '@reduxjs/toolkit';
import postReducer from "../features/post/posts.js";

export const store = configureStore({
    reducer: {
        posts: postReducer
    },
});

6.) Create a Posts.js in our component folder & import useSelector and useDispatch from the react-redux library:

import { useSelector, useDispatch } from "react-redux";
import { addPost, deletePost } from "../posts";

const PostList = () => {
    const dispatch = useDispatch();
    const posts = useSelector(state => state.posts.value);
    const renderedPosts = posts.map((p, i) => {
        return (
            <article
                key={p.id}>
                    <h3>{p.title}{p.id}</h3>
                    <p>{p.content.substring(0, 100)}</p>
                    <button onClick={()=> {
                        dispatch(deletePost({
                            id: p.id
                        }))
                    }}>X</button>
            </article>            
        )
    })
    return (
        <section>
            <h2>Posts</h2>
            {renderedPosts}
            <button onClick={() => {
                dispatch(addPost({
                    id: posts[posts.length - 1].id + 1, 
                    title: 'Testing', 
                    content: 'woo haa'
                }))
            }}>Submit</button>
        </section>

    )
}

export default PostList;

We can access the state through:

const posts = useSelector(state => state.posts.value);

We can dispatch through:

dispatch(addPost({
  id: posts[posts.length - 1].id + 1, 
  title: 'Testing', 
  content: 'woo haa'
}))

CreateAsyncThunk:

Summary

With Redux-toolkit we’re able to rid ourselves from having complex store configurations & unnecessary files following boilerplate. I’m planning to add more to this. Highly recommend reading through the Redux-toolkit docs for full comprehension.

  • No labels