i'm new and i'm trying to learn react and redux, I was trying to do this simple user list / todo list, I can add list items but I can't remove them with the remove in the reducer, if i click on the button it deletes all the array and the log of payload returns undefined, can someone help me? thanks all for the help!
STORE
import { combineReducers } from "@reduxjs/toolkit";
import { userState } from "./UsersState";
import { createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
const rootReducer = combineReducers({
users: userState.reducer,
});
export const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
REDUCER
import { createSlice, current } from "@reduxjs/toolkit";
export const userState = createSlice({
name: "users",
initialState: [],
reducers: {
add: (state, action) => [...state, action.payload],
remove: (state, action) =>
state.filter((user, index) => user.id !== action.payload),
clear: (state, action) => [],
log: (state, action) => console.log(state),
},
});
RENDER
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { store } from "./Store";
import { add, remove, clear, userState } from "./UsersState";
export function UsersList() {
const users = useSelector((state) => state.users);
const dispatch = useDispatch();
function addUser(event) {
event.preventDefault();
dispatch(userState.actions.add(event.target.elements.username.value));
dispatch(userState.actions.log());
}
function removeUser() {
dispatch(userState.actions.remove());
}
function clearList() {
dispatch(userState.actions.clear());
console.log(store.getState());
}
function logState() {
dispatch(userState.actions.log());
}
return (
<div>
<ul className="ul">
{users.map((user, index) => (
<div className="list-element" key={index + 1}>
<li key={index}>{user}</li>
<button onClick={removeUser} type="submit">
remove
</button>
</div>
))}
</ul>
<form onSubmit={addUser}>
<input name="username" type="text" />
Insert name
<button type="submit">Add user</button>
</form>
<button onClick={clearList}>Clear list</button>
<button onClick={logState}>Log state</button>
</div>
);
}
First of all, update the component like following (I commented on the place of change)
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { store } from "./Store";
import { add, remove, clear, userState } from "./UsersState";
// make sure to export these actions from the reducer file
export function UsersList() {
const users = useSelector((state) => state.users);
const dispatch = useDispatch();
function addUser(event) {
event.preventDefault();
dispatch(userState.actions.add(event.target.elements.username.value));
dispatch(userState.actions.log());
}
function removeUser() {
dispatch(userState.actions.remove());
}
function clearList() {
dispatch(userState.actions.clear());
console.log(store.getState());
}
function logState() {
dispatch(userState.actions.log());
}
return (
<div>
<ul className="ul">
{users.map((user, index) => (
<div className="list-element" key={index + 1}>
<li key={index}>{user}</li>
{/* you can directly dispatch the remove function*/}
{/* no need this button to be type="button"*/}
{/* change here */}
<button onClick={() => dispatch(remove(user))}>
remove
</button>
</div>
))}
</ul>
<form onSubmit={addUser}>
<input name="username" type="text" />
Insert name
<button>Add user</button>
</form>
<button onClick={clearList}>Clear list</button>
<button onClick={logState}>Log state</button>
</div>
);
}
You needed to pass user in the action and dispatch it, hope it helps!
For the reducer file, you have to export the actions also
import { createSlice, current } from "@reduxjs/toolkit";
export const userState = createSlice({
name: "users",
initialState: [],
reducers: {
add: (state, action) => [...state, action.payload],
remove: (state, action) =>
// need to redefine the state, forgot this part
// change here
state = state.filter((user, index) => user !== action.payload),
clear: (state, action) => [],
log: (state, action) => console.log(state),
},
});
export const {add, remove, clear, log} = userState.actions;
export default userState.reducer;