无法从异步 thunk 调度数据
Cannot dispatch data from async thunk
我创建了一个 redux 切片,async thunk,当我尝试访问状态时,我在控制台中得到了这个错误 类型错误:无法读取未定义的属性(读取 'educationList') 而且该应用程序无法运行。如果我将数据作为组件的道具,它可以工作,但是使用 redux thunk 它不会..你能告诉我我做错了什么吗?我正在使用 miragejs 模拟 api 数据,在控制台中我从服务器获取数据,但我无法将其映射到组件中,这是什么问题?
这是我的海市蜃楼服务器:
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 商店:
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;
我需要数据的组件:
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> </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
这是我在控制台中的内容:
但无法访问数据。请帮忙,我卡住了。提前致谢!
希望我解决了 problem.It 是在异步 thunk 得到 data.Above 的方法中,我使用了 axios,但只用 fetch 关键字替换它有帮助,所以,我的 educationSlice 现在看起来像这样:
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;
我用这种方式检索数据:
const educations = useSelector(state=>state.educationState.educationList.educations)
console.log(educations)
我创建了一个 redux 切片,async thunk,当我尝试访问状态时,我在控制台中得到了这个错误 类型错误:无法读取未定义的属性(读取 'educationList') 而且该应用程序无法运行。如果我将数据作为组件的道具,它可以工作,但是使用 redux thunk 它不会..你能告诉我我做错了什么吗?我正在使用 miragejs 模拟 api 数据,在控制台中我从服务器获取数据,但我无法将其映射到组件中,这是什么问题? 这是我的海市蜃楼服务器:
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 商店:
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;
我需要数据的组件:
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> </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
这是我在控制台中的内容:
但无法访问数据。请帮忙,我卡住了。提前致谢!
希望我解决了 problem.It 是在异步 thunk 得到 data.Above 的方法中,我使用了 axios,但只用 fetch 关键字替换它有帮助,所以,我的 educationSlice 现在看起来像这样:
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;
我用这种方式检索数据:
const educations = useSelector(state=>state.educationState.educationList.educations)
console.log(educations)