为什么我的嵌套React组件不会呈现?

时间:2017-04-30 23:39:28

标签: javascript reactjs create-react-app

我的React组件出现问题。我的组件ControlPanel的嵌套子项似乎没有呈现。这是我的代码:

class App extends Component {
  render() {
    return (
      <div className="App">
        <ControlPanel>
          <CustomerDisplay />
        </ControlPanel>
      </div>
    );
  }
}

我在这个文件的顶部有以下两行:

import ControlPanel from './components/control_panel';

import CustomerDisplay from './components/customer_display';

这是我的ControlPanel组件:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './styles.scss';

const ControlPanel = () => {
    return (
      <div className="control_panel" id="control_panel">

      </div>
    );
}

export default CSSModules(ControlPanel, styles);

我试过了:

  • 将组件称为完整的HTML标记(打开和关闭)
  • CustomerDisplay组件嵌套在ControlPanel组件中(在ControlPanel的index.jsx文件中)

我知道嵌套组件是可能的。我已经看到它完成了。出于某种原因,它对我不起作用。

5 个答案:

答案 0 :(得分:15)

要允许组件包含子组件并正确呈现它们,您必须使用this.props.children。这将传递给所有具有子项作为prop的组件,并包含组件的子项,如the React documentation所述:

  

遏制

     

有些成分提前不了解自己的孩子。这对于代表通用&#34;框&#34;的SidebarDialog等组件尤为常见。

     

我们建议此类组件使用特殊children道具将子元素直接传递到其输出

function FancyBorder(props) {
    return (
      <div className={'FancyBorder FancyBorder-' + props.color}>
        {props.children}
      </div>
    );
}
     

这允许其他组件通过嵌套JSX

将任意子项传递给它们
function WelcomeDialog() {
    return (
      <FancyBorder color="blue">
        <h1 className="Dialog-title">
          Welcome
        </h1>
        <p className="Dialog-message">
          Thank you for visiting our spacecraft!
        </p>
      </FancyBorder>
    );
}

如文档中所述,某些组件不会提前了解他们的孩子 - 他们可能是通用的包装器或内容框会有所不同,这就是您的ControlPanel。因此,要渲染组件的子项,您必须在父{m} children方法中明确地呈现render道具中的子项。因此,将它像这样应用到您的代码中:

const ControlPanel = (props) => {
    return (
      <div className="control_panel" id="control_panel">
        {props.children}
      </div>
    );
}

注意如何呈现props.children(不是this.props.children,因为它是一个功能组件)。

答案 1 :(得分:1)

您可以通过道具访问嵌套元素。所以在你的情况下这样做:

const ControlPanel = (props) => {
  return (
    <div className="control_panel" id="control_panel">
      {props.children}
    </div>
  );
}

答案 2 :(得分:1)

您需要在ControlPanel

中渲染子项
const ControlPanel = ({ children }) => {
    return (
      <div className="control_panel" id="control_panel">
        {children}
      </div>
    );
}

答案 3 :(得分:0)

你的App.js(我知道这是你的JSX索引)应该是:

import React from 'react';
import ReactDOM from 'react-dom';

export default class App extends Component {
render() {
return (
  <div className="App">
    <ControlPanel>
      <CustomerDisplay />
    </ControlPanel>
  </div>
);
}
}


ReactDOM.render(<App/>, document.getElementById('YOUR_ROOT_ID'));

尝试在export default之前添加class(在所有组件中)。

答案 4 :(得分:0)

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

export default function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
        <h1 className="Dialog-title">
           Welcome
        </h1>
        <p className="Dialog-message">
           Thank you for visiting our spacecraft!
        </p>
    </FancyBorder>
  );
}

<FancyBorder> JSX标记内的所有内容都以children prop的形式传递到FancyBorder组件中。由于FancyBorder在{props.children}内渲染<div>,所以传递的元素出现在最终输出中。

这就是我要照顾的,请在此处查看 https://reactjs.org/docs/composition-vs-inheritance.html