React中如何避免useReducer重复渲染?状态未合并问题求助
React useReducer 状态合并与冗余渲染问题解决
问题分析
- 每个
InputType组件单独实例化useReducer,导致两个组件维护完全独立的状态,自然无法得到合并后的{name: "MIKE", surname: "JORDAN"}——各自的state从INITIAL_STATE初始化,只会更新自身负责的字段。 - 将
useReducer移到父组件Office后,状态统一了,但父组件会因state变化触发重新渲染,连带导致两个InputType出现冗余渲染。
解决方案
- 统一状态管理:把
useReducer放在父组件Office中,维护全局表单状态,避免子组件各自为政。 - 改造受控组件:
InputType改为受控组件,接收父组件传递的value和onChange回调,不再自行维护状态。 - 削减冗余渲染:用
React.memo包裹InputType,仅当传入的props发生变化时才重新渲染。
修改后的代码
officeReducer(保持不变)
export const INITIAL_STATE = { name: "", surname: "", }; const ACTIONS = { CHANGE_INPUT: "CHANGE_INPUT", } export const officeReducer = (state, action) => { switch (action.type) { case ACTIONS.CHANGE_INPUT: return { ...state, [action.payload.name]: action.payload.value } default: { return state } } }
InputType.js
import React from "react"; // 用React.memo包裹,减少无意义的重新渲染 export const InputType = React.memo((props) => { const { value, onChange, id, type, required, name, placeholder } = props; return ( <div className={styles.inputBox}> <input id={id} type={type} required={required} name={name} value={value} onChange={onChange} /> <label htmlFor={id} className={value ? styles.inputFilled : ""} > {placeholder} </label> </div> ) })
Office.js
import { useReducer } from "react"; import { InputType } from "./InputType"; import { officeReducer, INITIAL_STATE } from "../../functions/officeReducer"; const Office = () => { const [state, dispatch] = useReducer(officeReducer, INITIAL_STATE); const handleChange = (e) => { dispatch({ type: "CHANGE_INPUT", payload: { name: e.target.name, value: e.target.value } }); }; return ( <div className={styles.dataBox}> <div className={styles.dataInputs}> <InputType placeholder={'Surname'} name={'surname'} required={true} type={'text'} value={state.surname} onChange={handleChange} /> <InputType placeholder={'Name'} name={'name'} required={true} type={'text'} value={state.name} onChange={handleChange} /> </div> </div> ) }
额外说明
- 移除了
InputType中多余的useState,直接用传入的value判断是否添加inputFilled样式,逻辑更统一。 React.memo会对InputType的props做浅比较,只有当value或onChange变化时才触发渲染,避免父组件state更新时的冗余渲染。
内容的提问来源于stack exchange,提问作者Gleymas
相关产品推荐
相关产品推荐

