Answer a question

I created a redux slice,async thunk,and when i try to access the state i get get this erro in console TypeError: Cannot read properties of undefined (reading 'educationList') And the app doesnt work. If i put the data as a prop from component,it works,but with redux thunk it doesnt.. Could you tell me what i'm doing wrong please? I'm using miragejs for mocking api data,and in console i get the data from the server,but i can not map it in the component,what is the problem? Here is my mirage server:

import { createServer,Model } from "miragejs"

export const makeServer =({ environment = 'test' } = {})  => {
    let server = createServer({
      environment,
        models: {
          educations: Model,
         skills:Model
        },

        seeds(server) {
            server.create("education", { date: 2001, title: "Title 0", text: "Elit voluptate ad nostrud laboris. Elit incididunt mollit enim enim id id laboris dolore et et mollit. Mollit adipisicing ullamco exercitation ullamco proident aute enim nisi. Dolore eu fugiat consectetur nulla sunt Lorem ex ad. Anim eiusmod do tempor fugiat minim do aliqua amet ex dolore velit.\r\n" });
            server.create("education", { date: 2000, title: "Title 1", text: "Et irure culpa ad proident labore excepteur elit dolore. Quis commodo elit culpa eiusmod dolor proident non commodo excepteur aute duis duis eu fugiat. Eu duis occaecat nulla eiusmod non esse cillum est aute elit amet cillum commodo.\r\n" });
            server.create("education", { date: 2012, title: "Title 2", text: "Labore esse tempor nisi non mollit enim elit ullamco veniam elit duis nostrud. Enim pariatur ullamco dolor eu sunt ad velit aute eiusmod aliquip voluptate. Velit magna labore eiusmod eiusmod labore amet eiusmod. In duis eiusmod commodo duis. Exercitation Lorem sint do aliquip veniam duis elit quis culpa irure quis nulla. Reprehenderit fugiat amet sint commodo ex.\r\n" });
          },
    
        routes() {
            //this.namespace = 'api/educations';
            this.get('api/educations', (schema, request) => {
              return schema.educations.all();
            });

            // this.namespace = 'api/skills';
            this.get('api/skills', (schema, request) => {
              return schema.skills.all();
            });
    

          this.post('api/skills', (schema, request) => {
            let attrs = JSON.parse(request.requestBody);
            return schema.skills.create(attrs);
          });
        },
      })
      return server;
    }  

redux store:

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension'
import { persistStore, persistReducer } from 'redux-persist'
import { toggleButtonReducer } from './reducers/toggleButtonReducer'
import storage from 'redux-persist/lib/storage'
import thunk from 'redux-thunk'
import { postSlice } from '../features/education/educationSlice';

const rootReducer = combineReducers({
    visibilityState: toggleButtonReducer,
    educationState: postSlice,
})

const persistConfig = {
    key: 'root',
    storage,
}

const persistedReducer = persistReducer(persistConfig, rootReducer)

export const store = createStore(persistedReducer, composeWithDevTools(applyMiddleware(thunk)))

export const persistor = persistStore(store)

educationSlice :

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from 'axios'

const initialState = {
    educationList: []
}


export const getEducation = createAsyncThunk(
    'educations/getEducations',
    async (_, { rejectWithValue, dispatch }) => {
        const res = await axios.get('api/educations')
        dispatch(setEducations(res.data))
        console.log(res.data)
    })


export const postSlice = createSlice({
    name: 'educations',
    initialState,
    reducers: {
        setEducations: (state, action) => {
            state.educationList = action.payload
        },
    },
    extraReducers:{
        [getEducation.fulfilled]:()=> console.log('fullfiled'),
        [getEducation.pending]:()=>console.log('fullfiled'),
        [getEducation.rejected]:() =>console.log('rejected'),
    },
})

export const {setEducations} = postSlice.actions
export default postSlice.reducer;

And the component were i need data:

import '../../assets/styles/css/TimeLine/base.css'
import { useDispatch } from 'react-redux'
import { getEducation } from '../../features/education/educationSlice'
import { store } from '../../store'
import { useSelector } from 'react-redux'

const TimeLine = () => {

const dispatch = useDispatch()
dispatch(getEducation())
const data = useSelector(state => state.educationState.educationList)

    return (
        <>
            <section id='timeLine'>
                <h1 className='educationSection'>Education</h1>
                <div id="timeline" className='timelineWrapper'>
                    {data.map((info) => (
                        <div className="timeline-item" key={info.id}>
                            <span className="timeline-icon">
                                <span>&nbsp;&nbsp;</span>
                                <span className="year">{info.date}</span>
                            </span>
                            <div className='timeline-content'>
                                <h2>{info.title}</h2>
                                <p>{info.text}</p>
                            </div>
                        </div>
                    ))}
                </div>
            </section>
        </>
    )
}

export default TimeLine  

This is what i have in console:
enter image description here

but can't acces the data.. please help,i'm stuck.. thanks in advance!

Answers

Hopefully i solved the problem.It was in the method which async thunk got the data.Above i used axios,but replacing just with fetch keyword it helped,so,my educationSlice now looks like this:

export const fetchEducations = createAsyncThunk(
    'educations/fetchEducations',
    async (_, {rejectWithValue}) => {
       try{
           const response = await fetch('/api/educations',{
               method:'GET',
           })
//  console.log(response)
           if(!response.ok){
               throw new Error ('Server Error!');

           }

           const data = await response.json();
// console.log(data)
           return data;
       } catch(error){
           return rejectWithValue(error.message);
       }
    }
    );


    const setError = (state, action) => {
        state.status = 'rejected';
        state.error = action.payload;
    }
    

export const educationSlice = createSlice({
    name: 'educations',
    initialState: {
        educationList: [],
        status: null,
        error: null,
    },
    reducers: {
        setEducations: (state, action) => {
            state.educationList = action.payload
        },
    },
    extraReducers: {
        [fetchEducations.pending]: (state, action) => {
            state.status = 'loading';
            state.error = null;
        },
        [fetchEducations.fulfilled]: (state, action) => {
            state.status = 'resolved';
            state.educationList = action.payload;
        },
        [fetchEducations.rejected]: setError,
    },
})

export const { setEducations } = educationSlice.actions
export default educationSlice.reducer;  

And i retrieve data this way:

const educations = useSelector(state=>state.educationState.educationList.educations)
console.log(educations)
Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐