繁体   English   中英

将 React 组件注入另一个 React 组件的最佳方法是什么? 还是我应该打扰?

[英]What's the best way to inject a React component into another React component? Or should I bother?

在开发我的第一个大型 React 应用程序时,我开始对嵌套组件的紧密耦合感到不安,尤其是在编写单元测试时。

如果是高级组件,并且其渲染函数返回<div><Bar><Baz /></Bar></div> ,我希望能够单独测试 Foo、Bar 和 Baz。

我寻求建议,但没有找到任何建议。 所以,我自己想出了两种注入方法:工厂函数和通过外部组件的属性。 (我不是在谈论儿童。我在谈论“烘焙”依赖项——人们通常通过 require 或 import 语句导入的那种。

特性

const Baz = React.createClass({
  render() {
    return <p>Inner</p>;
  }
});

const Foo = React.createClass({
  render() {
    const Bar = this.props.innerComponent;
    return <Bar />;
  }
});

ReactDOM.render(
  <Foo innerComponent={Baz} />,
  document.getElementById('container')
);

工厂

const Baz = React.createClass({
 render() {
   return <p>Inner</p>;
 }
});

const fooFactory = innerComponent => {
  return  React.createClass({
    render() {
      const Bar = innerComponent;
      return <Bar />;
   }
 });
};

const Foo = fooFactory(Baz);

ReactDOM.render(
  <Foo innerComponent={Baz} />,
  document.getElementById('container')
);

还是我只是把解耦走得太远了? 我在任何教程或示例中几乎没有看到其他人这样做。

你会倾向于有时注入组件而不是其他时间吗? 在什么情况下? 而且,如果你这样做了,你会使用上述技术之一还是其​​他方式?

当运行时需要指定一个组件类型时,您会不时看到这种模式,它传递给的组件将实例化它自己; 例如, React TransitionGroup组件采用这样一个名为component 的属性

默认情况下ReactTransitionGroup呈现为span 您可以通过提供component道具来更改此行为。 例如,以下是渲染<ul>

 <ReactTransitionGroup component="ul"> ... </ReactTransitionGroup>

React 可以渲染的每个 DOM 组件都可以使用。 但是, component不需要是 DOM 组件。 它可以是你想要的任何 React 组件; 甚至是你自己写的! 只需编写component={List} ,您的组件就会收到this.props.children

将此模式用于组件的用户指定内容不太常见,因为this.props.children更优雅地解决了这个问题。

但是,就测试而言,常见的解决方案是将每个组件单独导出并单独测试。 如果高级组件以某种方式组合它们,那么您真正需要测试的只是它们是否正确组合,因为这些组件也是单独测试的。

分离“智能”和“哑”组件有一个共同的模式; 愚蠢的组件只是渲染它们所给定的内容,并且非常容易进行单元测试。 智能组件可能会获取数据(例如通过 Ajax 或从通量存储)、组合特定的哑组件或做出其他“决定”,并且可能更难以测试——但同样,由于哑组件已经过测试,理想情况下您可以只需检查智能组件的行为是否正确并呈现正确的内容。

使用您的示例,渲染<div><Bar><Baz /></Bar></div>Foo工作 它是一个智能组件,测试应该确保它完全呈现。 然而, Bar的工作是渲染它的孩子,并且更容易测试。

您还可以使用TestUtils.mockComponent模拟组件。

查看mochajs 这个测试框架覆盖了import / require ,它解决了你的问题。

不过,这确实意味着您的子组件需要编写为 ECMA 6 或 NodeJS 模块 - 但这实际上只是意味着它们需要位于单独的源文件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM