reactjs - 如何防止 Redux 调度重新渲染子组件

标签 reactjs redux

我有以下组件:

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/

相关文章:

android - 如何使用 react-native 在 textInput 字段中自动获取 '/'(斜线)

reactjs - 使用 Material-ui v1.0.0-beta-1 中的类覆盖显示 "the key provided to the classes property is not implemented"警告

javascript - React.js 服务器端渲染和事件处理程序

javascript - Redux 工具包和 Axios

reactjs - React-Redux 中状态的生命周期是多少?

reactjs - react Redux 工具包 : No reducer provided for key "myReducer" when importing store to separate files

javascript - Redux:渲染时 props 未定义

reactjs - sass 在 create-react-app 中不起作用

javascript - 提交后重置输入字段

触发 closeOnDocumentClick 事件后,reactjs-popup 没有像以前一样打开