I'm learning redux, and i've a method addPosts
to add posts to the list of posts, and I'm doing it like this.
import { createSlice } from "@reduxjs/toolkit";
var initialState = [{ number: 1 }, { number: 2 }, { number: 3 }, { number: 4 }];
export const postsSlice = createSlice({
name: "postsSlice",
initialState,
reducers: {
addPost: (state, action) => {
state = [...state, action.payload];
},
},
});
export const allPosts = (state) => state.posts;
export const { addPost } = postsSlice.actions;
export default postsSlice.reducer;
and using the state like this.
import { useSelector, useDispatch } from "react-redux";
import { addPost, allPosts } from "./postsSlice";
function Posts() {
var posts = useSelector(allPosts);
var dispatch = useDispatch();
return (
<div>
{posts.map((post) => (
<div>{post.number}</div>
))}
{/* add post */}
<button
onClick={() => {
dispatch(addPost({ number: 1 }));
console.log(posts);
}}
>
addpost
</button>
</div>
);
}
export default Posts;
using state.push(action.payload)
works somehow, altough the documentation says not use update state like this, and update in an immutable way.
like this state = [...state, action.payload]
. it does not update state with this immutable way.
I don't know what is wrong that i'm doing. thanks in advance for any help
As per this instead of directly changing into state
you can return in this way
return [...state, action.payload]
Depending on your definition of initialState
Please have a look into working example of react-redux-toolkit-slice-example
Below is the definition of slice
import { createSlice } from "@reduxjs/toolkit";
const initialState = [{ number: 1 }];
export const postsSlice = createSlice({
name: "postsSlice",
initialState,
reducers: {
addPost: (state, action) => {
return [...state, action.payload];
}
}
});
export const allPosts = (state) => state.posts || [];
export const { addPost } = postsSlice.actions;
export default postsSlice.reducer;
Defining the reducer(postSlice) in store
import { configureStore } from "@reduxjs/toolkit";
import postsReducer from "../features/posts/postsSlice";
export default configureStore({
reducer: {
posts: postsReducer
}
});
Use of slice in component
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { addPost, allPosts } from "./postsSlice";
const Posts = () => {
var posts = useSelector(allPosts);
var dispatch = useDispatch();
return (
<div>
{posts.map((post, key) => (
<div key={key}>{post.number}</div>
))}
{/* add post */}
<button
onClick={() => {
dispatch(
addPost({
number: Math.max(...posts.map(({ number }) => number)) + 1
})
);
console.log(posts);
}}
>
Add Post
</button>
</div>
);
};
export default Posts;