【问题标题】:React pass x state variables to y {props.children}React 将 x 状态变量传递给 y {props.children}
【发布时间】:2021-08-04 10:21:48
【问题描述】:

我正在使用功能组件。我已经构建了我的独立组件并将它们放入我的index.js 文件中。

现在组件的结构是(伪代码):

<App stateVariable1={x} stateVariable2={y} stateVariable3={z}>
  <ChildOne props1={x} props2={y} />
  <ChildTwo props1={z}/>
</App>

ChildOne 和 ChildTwo 目前在 App.js 内呈现,因此将状态变量传递给两个孩子非常容易。

我想将渲染后的子元素提取到index.js 中,并用App.js 中的{props.children} 替换两个子元素,以增加组件的SRP 并使其更具可重用性。

但是,我很难理解如何在我的 index.js 文件中将多个状态变量作为多个 props 传递给 props.children

我已经阅读了 Render Props 的 react 文档,其中涉及将一个 prop 传递给单个子级,而不是多个想要接收不同 props 的子级。

我该如何实现我想做的事情?

更新

我已尝试按照此处接受的答案使用渲染道具:How to pass props to {this.props.children}

我的index.js 看起来像这样:

ReactDOM.render(
  <React.StrictMode>
    <App>
      {(stateVariable1) => (
        <Fragment>
          <ChildOne props1={stateVariable1} props2={stateVariable2} />
          <ChildTwo props3={stateVariable3} />
        </Fragment>
      )}
    </App>{' '}
  </React.StrictMode>,
  document.getElementById('root')
);

但是所有的 props/stateVariables 都存在未定义的错误,当然它们没有在 index.js 中定义。

我哪里错了?

更新 2:解决方案

我将所有状态变量作为参数传递给渲染道具,这解决了问题:

ReactDOM.render(
  <React.StrictMode>
    <App>
      {(stateVariable1, stateVariable2, stateVariable3) => (
        <Fragment>
          <ChildOne props1={stateVariable1} props2={stateVariable2} />
          <ChildTwo props3={stateVariable3} />
        </Fragment>
      )}
    </App>{' '}
  </React.StrictMode>,
  document.getElementById('root')
);

有没有办法解构它,这样我就不需要将每个参数传递给回调?我正在使用功能组件,因此状态存储在多个变量中,而不是在类组件的状态对象中。

【问题讨论】:

  • 你有效地回答了你自己的问题:D。您仍然可以使用useState({ stateVar1: ..., stateVar2: ... }) 将它们作为道具对象传递,但请注意,您需要将 App.js 中的对象替换为新对象,否则不会检测到更改。在你的孩子作为一个功能,你可以这样做:({ stateVar1, ...otherVars }) =&gt; (&lt;&gt;&lt;ChildOne stateVar1={stateVar1}/&gt;&lt;ChildTwo {...otherVars} /&gt;&lt;/&gt;)
  • @Tyblitz 谢谢,我应该在哪里使用useState 函数?
  • @Tyblitz 它按上述方式工作,现在不行,我收到错误消息:Warning: Functions are not valid as a React child. This may happen if you return a Component instead of &lt;Component /&gt; from render. Or maybe you meant to call this function rather than return it.
  • 抱歉,我认为useState 显然在App.js 中。您的错误似乎是您忘记在app.js 中调用props.children(stateVars)

标签: javascript reactjs


【解决方案1】:

我认为您可以避免完全使用props.children

如果您有如下结构,您的 SRP 原则仍然适用。

  • 应用程序
    • 孩子 1
    • 孩子 2

以上几行的意思是,您可以将Child1Child2 作为App 组件中的组件,而不是使用渲染道具模式或props.children

类似

const App = (props) => {
 return (
   <>
     <Child1 {...props} />
     <Child2 {...props} />
   </>
 );
}

如果您想让代码更通用并拥有一个 Children 组件,您可以将所有子组件提取到 index.js 文件中,这样您的 App 组件就不会受到影响,但老实说,这可能不需要.

【讨论】:

  • 谢谢。这就是我的应用程序当前的结构,让多个组件渲染责任落到这个组件上似乎是一种反模式。另外,掌握渲染道具会很好。
  • 我想我解决了自己的问题。不知道你能不能回答我最后一个问题,如何解构/传播 render prop 回调中的所有参数?
  • 让父级负责渲染所有子级根本不是一种反模式,大多数情况下你会遇到这种情况。即使在可读性方面,我认为前一个更具可读性,render props 只是稍微降低了可读性。至于解构,当前代码的编写方式没有直接的方法:(
【解决方案2】:

我在 Tyblitz 的帮助下解决了我的问题。

ReactDOM.render(
  <React.StrictMode>
    <App>
      {({stateVar1, stateVar2, ...stateVars}) => (
        <Fragment>
          <ChildOne props1={stateVar1} props2={stateVar2} />
          <ChildTwo {...stateVars} />
        </Fragment>
      )}
    </App>{' '}
  </React.StrictMode>,
  document.getElementById('root')
);

然后我将useState() 函数添加到我的App 组件中,并将所有状态变量作为对象传递。

最后,我将这个新的状态变量作为参数传递给我的返回调用:

return &lt;div className='App'&gt;{props.children(stateVars)}&lt;/div&gt;;

【讨论】:

    猜你喜欢
    • 2018-06-27
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 2019-03-08
    • 2021-12-01
    • 2019-06-25
    • 1970-01-01
    • 2019-01-20
    相关资源
    最近更新 更多