如何在React中用组件有条件地包装JSX

166 阅读2分钟

有时我们想让React中的内容被包裹在另一个组件中,而有时我们不想。在这篇文章中,我们创建了一个Wrapper ,它可以在一个组件中渲染它的孩子,也可以不这样做。

一个示例场景

假设我们有一些JSX,要么在应用中显示,要么在另一种情况下,在一个模态中显示。我们有一个Modal 组件,但我们不确定如何在其中有效地渲染JSX。

一个初步的方法

一种方法是重复内容,一次在模态内,一次不在模态内。然后,我们使用一个三元操作符来显示一个或另一个版本。

function MyComponent(props) {
  return (
    <div>
      <h1>Some content here</h1>
      <p>Some other content</p>
      {props.showModal ? (
        <Modal>
          <h2>Flexible content</h2>
          <p>This is some content that may be in a modal or may not.</p>
        </Modal>
      ) : (
        <>
          <h2>Flexible content</h2>
          <p>This is some content that may be in a modal or may not.</p>
        </>
      )}
    </div>
  );
}

当然,这是很难看的我们违反了编程的 "不要重复自己"(DRY)原则。我们可以把它做得更好的一个方法是把我们的重复内容存储在一个变量中。

function MyComponent(props) {
  const content = (
    <>
      <h2>Flexible content</h2>
      <p>This is some content that may be in a modal or may not.</p>
    </>
  );

  return (
    <div>
      <h1>Some content here</h1>
      <p>Some other content</p>
      {props.showModal ? <Modal>{content}</Modal> : content}
    </div>
  );
}

这样就可以把它清理得很干净了!但还有一种方法,我认为可以使我们的代码看起来更干净,并给我们更多的灵活性和可重用性--创建一个包装组件,让我们根据其道具来渲染内容。

一个包装器组件

让我们创建一个包装组件,它把showModal 作为一个道具。如果这个道具是真实的,我们就在一个模式中显示该组件的children 。如果不是,我们只是返回子句。

function Wrapper(props) {
  if (props.showModal) {
    return <Modal>{props.children}</Modal>;
  }
  return props.children;
}

然后,我们可以像这样把它拉入我们的其他组件。

function MyComponent(props) {
  return (
    <div>
      <h1>Some content here</h1>
      <p>Some other content</p>
      <Wrapper showModal={props.showModal}>
        <h2>Flexible content</h2>
        <p>This is some content that may be in a modal or may not.</p>
      </Wrapper>
    </div>
  );
}

我认为这看起来很干净。它给了我们更多的选择,我们可以在Wrapper 里面呈现什么(也许我们有两个以上的排列组合)。另外,Wrapper 现在是可重复使用的,以防在整个应用中出现这种模式。