我有以下组件:
import * as React from "react";
import {useAppDispatch, useAppSelector} from "./store/hook";
import {fetchUser} from "./store/slices/user/auth-slice";
import {useDispatch} from "react-redux";
function App() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchUser());
}, [])
const [loading, error] = useAppSelector((state: any) => [
state.auth.loading,
state.auth.error,
])
return (
<>
{loading ? (
<div
className="d-flex align-items-center justify-content-center"
style={{ height: "100vh" }}
>
<CircularProgress color="inherit" />
</div>
) : (
<Layout>
<Suspense fallback={<CircularProgress color="inherit" />}>
<Routes>
<Route path="/" element={<Navigate to="/regions/" replace />}/>
<Route path="ipam" element={<Ips />}/>
</Routes>
</Suspense>
</Layout>
)}
</>
);
}
export default App;
存储/切片/用户/验证切片:
import {createAsyncThunk, createSlice} from "@reduxjs/toolkit";
import UserModel from "models/userAction";
import axios from "api/axios-base";
import {getUserDetails} from "../../../api/services";
import {useAppDispatch} from "../../hook";
export const fetchUser = createAsyncThunk('auth/user', async () => {
return getUserDetails().then((response) => {
return response.data;
}).catch(err => {
return err;
})
})
const initialState: UserModel = {
user_id: null,
email: '',
name: '',
isLoggedIn: false,
loading: false,
error: false,
}
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
Login(state: any, action: any) {
state = {
...initialState,
isLoggedIn: true
}
return state;
}
},
extraReducers: builder => {
builder
.addCase(fetchUser.pending, (state, action) => {
state = {
...initialState,
loading: true
}
return state;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state = {
...initialState,
...action.payload.data,
isLoggedIn: true,
loading: false
}
return state;
})
.addCase(fetchUser.rejected, (state) => {
state = {
...initialState,
loading: false
}
return state;
});
}
});
export const authActions = authSlice.actions;
export default authSlice;
现在的问题是 Ips
,它是 App 的子组件,渲染两次:
function Ips() {
useEffect(() => {
alert('test')
}, [])
return (
<div className={classes.Ip}>
test
</div>
);
}
export default Ips;
因此运行警报(“测试”)两次,我发现问题出现在我的 authSlice 中的这部分代码变为加载 True 然后使其为 false 后,当我comemnt它时,没有发生重新渲染放置在子组件内。
builder
.addCase(fetchUser.pending, (state, action) => {
state = {
...initialState,
loading: true
}
return state;
})
如何防止这种重新渲染?
最佳答案
问题是您在调用第一个 fetchUser
API 时重新渲染所有应用路由。子组件 Ips
没有重新渲染,它实际上是重新安装。
最简单的解决方案和 IMO 仍然正确(不是解决方法):loading
的初始值应该是 true
const initialState: UserModel = {
user_id: null,
email: '',
name: '',
isLoggedIn: false,
loading: true, // <--- `true` instead of `false`
error: false,
}
关于reactjs - 如何防止 Redux 调度重新渲染子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72519740/