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

向组件传递状态及状态修改器的最佳实践

如何简化React组件中大量传递的Props?

我正在重构一个接收大量props的组件,想参考高级React模式优化。针对如下代码,希望减少props数量或对其分组,有没有能把关联状态和状态修改器分组的模式?

const App = () => {
    const [ab, setAb] = useState();
    const [c, setC] = useState();
    const [d, setD] = useState();

    // stuff with all available state
    return (<Example ab={ab} setAb={setAb} c={c} setC={setC} d={d} setD={setD} />)
} 

const Example = ({ab, setAb, c, setC, d, setD}) => {
   const [a, setA] = useState();

    // stuff with all available vars
   return  (
        <>
          <A ab={ab} setAb={setAb}  a={a} setA={setA}/>
          <B ab={ab} setAb={setAb}/>
          <C c={c} setC={setC} d={d} setD={setD}/>
        </>      
    )
}

const A = ({ab, setAb, a, setA}) => {
     // stuff with all available vars
    return <div>{a}</div>
}

const B = ({ab, setAb}) => {
    // stuff with setAb
   return <div>{ab}</div>
}

const C = ({c, setC, d, setD}) => {
    // stuff with all available vars
    return (<D d={d} setD={setD} />)
}

const D = ({d, setD}) => {
    // stuff with setAb
   return (<div>{d}</div>);
}

方案1:关联状态与修改器分组传递

把逻辑相关的状态和setter打包成对象传递,既减少单个props的数量,又能保持状态的关联性:

修改后代码示例

const App = () => {
    const [ab, setAb] = useState();
    const [c, setC] = useState();
    const [d, setD] = useState();

    // 分组关联状态
    const abState = { value: ab, setValue: setAb };
    const cState = { value: c, setValue: setC };
    const dState = { value: d, setValue: setD };

    return (<Example abState={abState} cState={cState} dState={dState} />)
} 

const Example = ({abState, cState, dState}) => {
   const [a, setA] = useState();
   const aState = { value: a, setValue: setA };

   return  (
        <>
          <A abState={abState} aState={aState}/>
          <B abState={abState}/>
          <C cState={cState} dState={dState}/>
        </>      
    )
}

const A = ({abState, aState}) => {
    // 解构使用
    const { value: ab, setValue: setAb } = abState;
    const { value: a, setValue: setA } = aState;
    return <div>{a}</div>
}

const B = ({abState}) => {
    const { value: ab, setValue: setAb } = abState;
    return <div>{ab}</div>
}

const C = ({cState, dState}) => {
    return (<D dState={dState} />)
}

const D = ({dState}) => {
    const { value: d, setValue: setD } = dState;
    return (<div>{d}</div>);
}

方案2:用React Context避免层层透传

如果多个层级的组件都依赖同一组状态,直接通过Context共享,彻底消除props透传的问题:

修改后代码示例

// 按使用范围拆分Context
const AbContext = React.createContext();
const CDContext = React.createContext();

const App = () => {
    const [ab, setAb] = useState();
    const [c, setC] = useState();
    const [d, setD] = useState();

    return (
        <AbContext.Provider value={{ ab, setAb }}>
            <CDContext.Provider value={{ c, setC, d, setD }}>
                <Example />
            </CDContext.Provider>
        </AbContext.Provider>
    )
} 

const Example = () => {
   const [a, setA] = useState();

   return  (
        <>
          <A a={a} setA={setA}/>
          <B />
          <C />
        </>      
    )
}

const A = ({a, setA}) => {
    const { ab, setAb } = useContext(AbContext);
    return <div>{a}</div>
}

const B = () => {
    const { ab, setAb } = useContext(AbContext);
    return <div>{ab}</div>
}

const C = () => {
    return (<D />)
}

const D = () => {
    const { d, setD } = useContext(CDContext);
    return (<div>{d}</div>);
}

拆分多个Context可以避免单个Context过于庞大,也能让组件只订阅自己需要的状态。

方案3:自定义Hook封装状态逻辑

把关联的状态和操作封装成自定义Hook,组件通过调用Hook直接获取状态,减少props传递:

修改后代码示例

// 封装ab相关状态逻辑
const useAbState = () => {
    const [ab, setAb] = useState();
    // 可在此添加ab相关的业务逻辑
    return { ab, setAb };
};

// 封装cd相关状态逻辑
const useCDState = () => {
    const [c, setC] = useState();
    const [d, setD] = useState();
    return { c, setC, d, setD };
};

const App = () => {
    const abState = useAbState();
    const cdState = useCDState();

    return (<Example {...abState} {...cdState} />)
} 

const Example = () => {
   const [a, setA] = useState();
   const abState = useAbState();

   return  (
        <>
          <A {...abState} a={a} setA={setA}/>
          <B {...abState}/>
          <C {...useCDState()}/>
        </>      
    )
}

// 组件直接调用Hook获取状态
const A = () => {
    const { ab, setAb } = useAbState();
    const [a, setA] = useState();
    return <div>{a}</div>
}

const B = () => {
    const { ab, setAb } = useAbState();
    return <div>{ab}</div>
}

const C = () => {
    const { d, setD } = useCDState();
    return (<D />)
}

const D = () => {
    const { d, setD } = useCDState();
    return (<div>{d}</div>);
}

注意:如果需要组件间共享同一份状态,这种方式要配合Context或状态管理库,否则不同组件调用Hook会生成独立的状态实例。

方案4:按功能拆分组件

根据状态的使用范围拆分组件,让每个组件只负责自己相关的状态和UI,缩小状态作用域:

修改后代码示例

const App = () => {
    return (
        <>
            <AbSection />
            <CDSection />
        </>
    )
} 

// 封装ab相关的所有UI和状态
const AbSection = () => {
    const [ab, setAb] = useState();
    const [a, setA] = useState();

    return  (
        <>
          <A a={a} setA={setA} ab={ab} setAb={setAb}/>
          <B ab={ab} setAb={setAb}/>
        </>      
    )
}

// 封装cd相关的所有UI和状态
const CDSection = () => {
    const [c, setC] = useState();
    const [d, setD] = useState();

    return <C c={c} setC={setC} d={d} setD={setD}/>
}

// 子组件保持原有逻辑,只接收自身需要的props
const A = ({ab, setAb, a, setA}) => {
    return <div>{a}</div>
}

const B = ({ab, setAb}) => {
    return <div>{ab}</div>
}

const C = ({c, setC, d, setD}) => {
    return (<D d={d} setD={setD} />)
}

const D = ({d, setD}) => {
    return (<div>{d}</div>);
}

这种方式让状态的作用域更清晰,彻底避免跨层级的props透传问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:58:10