You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React父组件托管状态时,如何避免子组件间不必要重渲染?

解决React父子组件不必要重渲染的方案(排除React.memo)

方案一:拆分独立状态容器组件

核心思路是将每个表单的状态管理封装到独立容器组件中,容器内部维护自身局部状态,同时将数据同步到父组件的聚合状态。这样每个容器的重渲染仅影响自身,不会波及另一个表单组件。

示例代码:

import React, { useState, useEffect } from "react";

// FormA的独立容器组件,内部管理状态并同步到父组件
const FormAContainer = ({ onDataChange }) => {
  const [dataA, setDataA] = useState("");

  // 将局部状态同步到父组件聚合数据
  useEffect(() => {
    onDataChange(dataA);
  }, [dataA, onDataChange]);

  useEffect(() => {
    console.log("Form A was just rendered");
  });

  return (
    <div>
      <input onChange={(e) => setDataA(e.target.value)} />
      <p>Input Form A: {dataA}</p>
    </div>
  );
};

// FormB的独立容器组件
const FormBContainer = ({ onDataChange }) => {
  const [dataB, setDataB] = useState("");

  useEffect(() => {
    onDataChange(dataB);
  }, [dataB, onDataChange]);

  useEffect(() => {
    console.log("Form B was just rendered");
  });

  return (
    <div>
      <input onChange={(e) => setDataB(e.target.value)} />
      <p>Input Form B: {dataB}</p>
    </div>
  );
};

export function BigForm() {
  const [aggregatedData, setAggregatedData] = useState({
    dataA: "",
    dataB: ""
  });

  // 接收FormA同步的数据
  const handleDataAChange = (value) => {
    setAggregatedData(prev => ({ ...prev, dataA: value }));
  };

  // 接收FormB同步的数据
  const handleDataBChange = (value) => {
    setAggregatedData(prev => ({ ...prev, dataB: value }));
  };

  // 此处可使用聚合数据做后续操作
  useEffect(() => {
    console.log("Aggregated data updated:", aggregatedData);
  }, [aggregatedData]);

  return (
    <div className="App">
      <FormAContainer onDataChange={handleDataAChange} />
      <FormBContainer onDataChange={handleDataBChange} />
    </div>
  );
}

方案二:Redux状态管理

通过Redux全局管理表单数据,让每个子组件仅订阅自身需要的状态,触发对应action更新数据,实现精准的重渲染控制。

1. 安装依赖

npm install @reduxjs/toolkit react-redux

2. 创建Redux Store与Slice

// src/store/formSlice.js
import { createSlice } from '@reduxjs/toolkit';

const formSlice = createSlice({
  name: 'form',
  initialState: {
    dataA: '',
    dataB: ''
  },
  reducers: {
    updateDataA: (state, action) => {
      state.dataA = action.payload;
    },
    updateDataB: (state, action) => {
      state.dataB = action.payload;
    }
  }
});

export const { updateDataA, updateDataB } = formSlice.actions;
export default formSlice.reducer;

// src/store/index.js
import { configureStore } from '@reduxjs/toolkit';
import formReducer from './formSlice';

export const store = configureStore({
  reducer: {
    form: formReducer
  }
});

3. 配置全局Provider(入口文件)

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './store';
import { BigForm } from './BigForm';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <BigForm />
  </Provider>
);

4. 修改表单组件与父组件

// src/BigForm.js
import React, { useEffect } from "react";
import { useSelector, useDispatch } from 'react-redux';
import { updateDataA, updateDataB } from './store/formSlice';

const FormA = () => {
  const dataA = useSelector(state => state.form.dataA);
  const dispatch = useDispatch();

  useEffect(() => {
    console.log('Form A was just rendered');
  });

  return (
    <div>
      <input onChange={(e) => dispatch(updateDataA(e.target.value))} />
      <p>Input Form A: {dataA}</p>
    </div>
  );
};

const FormB = () => {
  const dataB = useSelector(state => state.form.dataB);
  const dispatch = useDispatch();

  useEffect(() => {
    console.log('Form B was just rendered');
  });

  return (
    <div>
      <input onChange={(e) => dispatch(updateDataB(e.target.value))} />
      <p>Input Form B: {dataB}</p>
    </div>
  );
};

export function BigForm() {
  // 获取聚合后的表单数据用于后续操作
  const aggregatedData = useSelector(state => state.form);

  useEffect(() => {
    console.log('Aggregated data updated:', aggregatedData);
  }, [aggregatedData]);

  return (
    <div className="App">
      <FormA />
      <FormB />
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Ae Leung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:27:23