在 React 中的渲染中传播一组组件

nei*_*iya 5 javascript reactjs

我目前将一个组件数组渲染为另一个组件的子组件,如下所示:

\n\n
const myComponents = [\n  <div key=\'1\'>Component 1</div>,\n  <div key=\'2\'>Component 2</div>,\n  <div key=\'3\'>Component 3</div>,\n];\n\nrender() {\n  return (\n    <AnotherComponent>\n      {myComponents}\n      <div>Another element</div>\n    </ AnotherComponent>\n  )\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的问题是里面AnotherComponent,我的组件数组呈现为数组(这是有道理的):

\n\n
// Inside AnotherComponent\nconsole.log(this.props.children) // [[ {}, {}, {} ], {} ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的预期输出是组件应该“传播”,如下所示:

\n\n
// Inside AnotherComponent\nconsole.log(this.props.children) // [ {}, {}, {}, {} ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经尝试过map渲染中的组件,但输出是相同的:

\n\n
const myComponents = [\n  ...\n];\n\nrender() {\n  return (\n    <AnotherComponent>\n      {myComponents.map(component => component)}\n      <div>Another element</div>\n    </ AnotherComponent>\n  )\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以通过将里面的孩子们展平来实现这一点AnotherComponent。但我想知道是否有一种语法可以让我之前将其展平,以便AnotherComponent干净了。

\n\n

我想实现这一点的原因是因为我在里面做了一些复杂的布局渲染AnotherComponent。这要求子项不能是数组,除非我明确想要它,但这里的情况并非如此。

\n\n

编辑:这是一个包含我当前输出和预期输出的演示:

\n\n

\r\n
\r\n
const components = [\r\n  <div>Component 1</div>,\r\n  <div>Component 2</div>,\r\n  <div>Component 3</div>,\r\n];\r\n\r\nconst MyLayoutComponent = ({ children }) => {\r\n  console.log(\'\xe2\x9d\x8c Current output\', children);\r\n  console.log(\'\xe2\x9c\x85 Expected output\', children.flat());\r\n  return <div>{children}</div>\r\n}\r\n\r\nconst App = () => (\r\n  <MyLayoutComponent>\r\n    {components}\r\n    <div>Some other component</div>\r\n  </MyLayoutComponent>\r\n);\r\n\r\nReactDOM.render(<App />, document.body)
Run Code Online (Sandbox Code Playgroud)\r\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>\r\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

T.J*_*der 3

事实上,它们以数组的形式出现是合适的,而且很有用,因为如果列表的顺序根据以下内容发生变化,React 可以优化重新渲染:key。事实上它们位于一个数组中,这使得 React 寻找一个键。

\n\n

如果您不希望它们本身成为列表,您可以使用片段代替:

\n\n
const myComponents = <>\n  <div>Component 1</div>\n  <div>Component 2</div>\n  <div>Component 3</div>\n</>;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这仍将作为单个条目出现props.children,但该条目将是一个片段,而不是一个数组,并且 React 不需要其上的键等。

\n\n

我能想到的唯一其他答案是将其他组件也放入一个数组中(但这需要它们有一个key):

\n\n
const App = () => (\n  <MyLayoutComponent>\n    {[...components, <div key="other">Some other component</div>]}\n  </MyLayoutComponent>\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

\r\n
\r\n
const myComponents = <>\n  <div>Component 1</div>\n  <div>Component 2</div>\n  <div>Component 3</div>\n</>;\n
Run Code Online (Sandbox Code Playgroud)\r\n
const App = () => (\n  <MyLayoutComponent>\n    {[...components, <div key="other">Some other component</div>]}\n  </MyLayoutComponent>\n);\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

或者为这种情况放弃 JSX 并编写createElement直接编写调用:

\n\n
const App = () => React.createElement(\n  MyLayoutComponent,\n  {\n    children: [\n      ...components,\n      <div>Some other component</div>\n    ]\n  }\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

\r\n
\r\n
const components = [\r\n  <div>Component 1</div>,\r\n  <div>Component 2</div>,\r\n  <div>Component 3</div>,\r\n];\r\n\r\nconst MyLayoutComponent = ({ children }) => {\r\n  console.log(\'\xe2\x9c\x85 Current child count\', children.length);\r\n  console.log(\'\xe2\x9c\x85 Expected child count\', children.flat().length);\r\n  return <div>{children}</div>\r\n}\r\n\r\nconst App = () => (\r\n  <MyLayoutComponent>\r\n    {[...components, <div key="other">Some other component</div>]}\r\n  </MyLayoutComponent>\r\n);\r\n\r\nReactDOM.render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)\r\n
<div id="root"></div>\r\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>\r\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

我想不出 JSX 的方法来做到这一点。

\n