Why can't I access state object in my reduer in redux?

Viewed 37

I can't seem to figure out how to use redux. I want to save an array of lists to the local storage and add a new list each time but I'm getting undefined for the lists variable. ............................................................................ This is my store

store.js

import { createStore, compose, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { listsReducer } from "./reducers/ListsReducer";

const initialState = {
    lists: localStorage.getItem('lists')
        ?JSON.parse(localStorage.getItem('lists'))
        :[]
}

const reducer = combineReducers({
    lists: listsReducer
});

const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
    reducer,
    initialState,
    composeEnhancer(applyMiddleware(thunk))
);
export default store;

........................................................................... My reducer

ListsReducer.js

import { LISTS_ADD_LIST } from "../constants/ListsConstants";

export const listsReducer = (state = {lists:[]}, action) =>{
    switch(action.type){
        case LISTS_ADD_LIST:
             const list = action.payload;
             return {
                    ...state,
                    lists: [...state.lists, list]
             };
        default:
            return state;
   }
}

........................................................................... ListsConstants.js

export const LISTS_ADD_LIST = 'LISTS_ADD_LIST';

........................................................................... index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import App from './App';
import store from './store';

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

................................................................................ App.js

import {BrowserRouter} from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { addNewList } from "../actions/ListsActions";

function App() {
    const dispatch = useDispatch();
    const addList = ()=>{
        var date_time = new Date().toLocaleString();
        var title = 'my list '+date_time;

        var list = {
            _id:date_time,
            title:title,
            items:[]
        };
        dispatch(addNewList(list));
    }

    return(
         <div>
             <button onClick={addList}> </button>
         </div>
    );

}

................................................................................ ListsActions.js

import { LISTS_ADD_LIST } from "../constants/ListsConstants";

export const addNewList = (list) => async(dispatch, getState) => {
    dispatch({
        type: LISTS_ADD_LIST,
        payload: list
    });
    localStorage.setItem('lists', JSON.stringify(getState().lists));
};
1 Answers

this is how i am doing it, its pretty straight forward

the component

import { RootStateOrAny, useDispatch, useSelector } from 'react-redux'
import { profileAction } from '../../redux/features/profile/profileSlice'

export const AboutComponent = () => {
    const dispatch = useDispatch()
    const about = useSelector((state) => state.profile.about) //getting the value

    const handlechange = (e) => {
       dispatch(profileAction({ case: "about", value: e.target.value })) //adding the value
    }

index.js is the same

ReactDOM.render(
   <Provider store={store}>
     <App />
   </Provider>,
   document.getElementById('root')
);

the slice

import {createSlice} from '@reduxjs/toolkit' //<-- package to install
import { payloadValue } from './payloadValue'

const initialStateValue = {
   name: null,
   birthDate: null,
   county: null,
   about: "",
}

export const profileSlice = createSlice({
    name: "profile",
    initialState:  initialStateValue,

    reducers: {
        profileAction: (state = initialStateValue, action) => {
           return payloadValue(state, action)
       }
    }
})

export const {profileAction} = profileSlice.actions

export default profileSlice.reducer

my function

export const payloadValue = (state, action) => {
    switch (action.payload.case) {
        case "name":
           return {...state, name: action.payload.value}
        case "birthDate":
           return {...state, birthDate: action.payload.value}
        case "county":
           return {...state, county: action.payload.value}
        case "about":
           return {...state, about: action.payload.value}
        default:
           return state
    }
}

the store

import {configureStore} from '@reduxjs/toolkit'
import userReducer from "./features/user/userSlice"
import profileReducer from "./features/profile/profileSlice"

export const store = configureStore ({
    reducer: {
       //user: userReducer,
       profile: profileReducer,
    },
})
Related