在 React.js 中,有没有办法为所有子组件提供特定的道具?

问题描述 投票:0回答:1

感谢您看到这个问题,也感谢您对这个问题的思考

我正在寻找为 React.js 中的整个子组件提供特定道具的方法

我知道在这种情况下,我们通常使用 context 或像 recoil 这样的存储包,并从下面的子组件中获取数据。

在这个例子中,父组件通过上下文将

disabled
状态传递给子组件,子组件使用
useContext
使用提供的数据。

const DisableContext = createContext({});

const ParentComponent = () => {
  const [disabled, setDisabled] = useState(false);
  return (
    <DisableContext.Provider value={{ disabled }}>
      <button onClick={() => setDisabled((old) => !old)}>{disabled ? 'Disabled' : 'Enabled'}</button>
      <ChildComponent />
    </DisableContext.Provider>
  )
}

const ChildComponent = () => {
  const { disabled } = useContext(DisableContext);
  return (
    <div>
      <p>ChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
      <GrandChildComponent />
    </div>
  )
}

const GrandChildComponent = () => {
  const { disabled } = useContext(DisableContext);
  return (
    <div>
      <p>GrandChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
    </div>
  )
}

但在我的例子中,我想将数据传递给整个子组件

props
。而且我不想在每个子组件中编写消费代码(在这种情况下为
useContext
)。

我知道

cloneElement
可以覆盖子组件的原始道具,并且可以使用它来传递道具而无需在子组件中编码消费代码,如下所示。

然而,在下面的例子中,孙子组件无法监听祖父组件 props 的变化。只有直接子组件才能通过 props 监听

disabled

或者,我们可以递归地应用

cloneElement
将道具传递给整个子组件。但我知道这可能是一个繁重的过程,我想避免这种模式。

有什么好的方法可以达到我的要求吗?


const DisableWrapperComponentWhichPassesDisabledAsProps = ({ children, disabled }) => {
  return cloneElement(children, { disabled })
}

const ParentComponent = () => {
  const [disabled, setDisabled] = useState(false);

  return (
    <>
      <button onClick={() => setDisabled((old) => !old)}>{disabled ? 'Disabled' : 'Enabled'}</button>
      <DisableWrapperComponentWhichPassesDisabledAsProps disabled={disabled}>
        <ChildComponent />
      </DisableWrapperComponentWhichPassesDisabledAsProps>
    </>
  )
}

const ChildComponent = ({ disabled }) => {
  return (
    <div>
      <p>ChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
      <GrandChildComponent />
    </div>
  )
}

const GrandChildComponent = ({ disabled }) => {
  return (
    <div>
      <p>GrandChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
    </div>
  )
}

[我试过的]

  1. 我用
    cloneElement
    试过,但我发现它不能满足我的要求。
  2. 我用递归模式试过了。可以达到我的要求,但是过程会很重

[我期待的]

  1. 将 { disabled: boolean } 属性传递给整个子组件
  2. 我希望子组件是简单的反应组件,它应用
    disabled
    作为道具,没有任何特殊的消费代码,如
    useContext
    或其他东西。
javascript reactjs components react-props
1个回答
0
投票

道具可以根据需要向下传递。这样的事情应该可以解决问题:

const ParentComponent = () => {
  const [disabled, setDisabled] = useState(false);
  return (
    <button onClick={() => setDisabled((old) => !old)}>{disabled ? 'Disabled' : 'Enabled'}</button>
    <ChildComponent disabled={disabled} />
  )
}

const ChildComponent = ({ disabled }) => {
  return (
    <div>
      <p>ChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
      <GrandChildComponent disabled={disabled} />
    </div>
  )
}

const GrandChildComponent = ({ disabled }) => {
  return (
    <div>
      <p>GrandChildComponent</p>
      <span>Parent is {disabled ? 'Disabled' : 'Enabled'}</span>
    </div>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.