如何让 useAppSelector 等待来自 Get 请求的数据(而不是显示初始数据)
how to make useAppSelector wait for data from Get request (instead of showing initial data)
我有这个减速器
import { createSlice } from "@reduxjs/toolkit";
export const projectSlice = createSlice({
name: "project-redux",
initialState: {
name: "",
},
reducers: {
get_project: (state, action) => {
axios
.get("http://localhost:5000/api/project/" + action.payload)
.then((res) => {
state = res.data; //which contains the name
});
},
},
});
export const { get_project } = projectSlice.actions;
export default projectSlice.reducer;
并想使用 useAppSelector
访问“名称”
const dispatch = useAppDispatch();
const {name}=useAppSelector(state=>state.projs) //projs is the name of projectsReducer in the store
console.log(name) // only give initial state
get请求完成后如何获取'name'值?
解决方案:
export const fetchProject = createAsyncThunk(
"fetchProject",
async (id) => {
const res = await axios.get("http://localhost:5000/api/project/" + id);
return res.data.title;
}
);
reducers: {//other reducers if ther is}
extraReducers: (builder) => {
builder.addCase(fetchProject.fulfilled, (state, action) => {
state.title = action.payload;
});
},
然后:
const name = useAppSelector((state) => state.projs.title);
console.log("selecttitle", name);
您不能将副作用(I/O 操作)代码放入 reducer 函数中。 redux reducer 函数应该是纯的。您应该使用 createAsyncThunk 来获取数据。
分派异步 thunk 后,您应该使用 createSlice
的 extraReducers
字段中获取的数据改变状态。改变状态后,组件将重新渲染,然后 useAppSelector
将被调用。您将从 redux 存储中读取从远程服务器获取的状态。
例如
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
import { useEffect } from 'react';
export const fetchProject = createAsyncThunk('fetchProject', (id) => {
return axios.get('http://localhost:5000/api/project/' + id).then((res) => res.data);
});
export const projectSlice = createSlice({
name: 'project-redux',
initialState: {
name: '',
},
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchProject.fulfilled, (state, action) => {
state.name = action.payload;
});
},
});
export default projectSlice.reducer;
// Component
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
function Test() {
const dispatch = useDispatch();
const { name } = useSelector((state) => state.projs);
useEffect(() => {
dispatch(fetchProject('1'));
}, [dispatch]);
return <div>{name}</div>;
}
我有这个减速器
import { createSlice } from "@reduxjs/toolkit";
export const projectSlice = createSlice({
name: "project-redux",
initialState: {
name: "",
},
reducers: {
get_project: (state, action) => {
axios
.get("http://localhost:5000/api/project/" + action.payload)
.then((res) => {
state = res.data; //which contains the name
});
},
},
});
export const { get_project } = projectSlice.actions;
export default projectSlice.reducer;
并想使用 useAppSelector
访问“名称”const dispatch = useAppDispatch();
const {name}=useAppSelector(state=>state.projs) //projs is the name of projectsReducer in the store
console.log(name) // only give initial state
get请求完成后如何获取'name'值?
解决方案:
export const fetchProject = createAsyncThunk(
"fetchProject",
async (id) => {
const res = await axios.get("http://localhost:5000/api/project/" + id);
return res.data.title;
}
);
reducers: {//other reducers if ther is}
extraReducers: (builder) => {
builder.addCase(fetchProject.fulfilled, (state, action) => {
state.title = action.payload;
});
},
然后:
const name = useAppSelector((state) => state.projs.title);
console.log("selecttitle", name);
您不能将副作用(I/O 操作)代码放入 reducer 函数中。 redux reducer 函数应该是纯的。您应该使用 createAsyncThunk 来获取数据。
分派异步 thunk 后,您应该使用 createSlice
的 extraReducers
字段中获取的数据改变状态。改变状态后,组件将重新渲染,然后 useAppSelector
将被调用。您将从 redux 存储中读取从远程服务器获取的状态。
例如
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
import { useEffect } from 'react';
export const fetchProject = createAsyncThunk('fetchProject', (id) => {
return axios.get('http://localhost:5000/api/project/' + id).then((res) => res.data);
});
export const projectSlice = createSlice({
name: 'project-redux',
initialState: {
name: '',
},
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchProject.fulfilled, (state, action) => {
state.name = action.payload;
});
},
});
export default projectSlice.reducer;
// Component
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
function Test() {
const dispatch = useDispatch();
const { name } = useSelector((state) => state.projs);
useEffect(() => {
dispatch(fetchProject('1'));
}, [dispatch]);
return <div>{name}</div>;
}