在处理我的第一个大型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')
);
或者我只是把脱钩过度了?我在任何教程或示例中都看不到其他任何人这样做。
您是否倾向于有时注射组件而不是其他时间?在什么情况下?而且,如果你这样做了,你会使用上述技术之一还是以其他方式做到这一点?
答案 0 :(得分:1)
这是一种模式,您不时会看到有必要指定一个组件 type ,它传递给的组件将实例化自己;例如,the React TransitionGroup
component takes such a property名为component
:
默认情况下,
ReactTransitionGroup
呈现为span
。您可以通过提供component
道具来更改此行为。例如,以下是如何呈现<ul>
:<ReactTransitionGroup component="ul"> ... </ReactTransitionGroup>
React可以渲染的每个DOM组件都可以使用。但是,
component
不需要是DOM组件。它可以是您想要的任何React组件;即使是你自己写的!只需撰写component={List}
,您的组件就会收到this.props.children
。
将此模式用于组件的用户指定的内容并不常见,因为this.props.children
可以更优雅地解决此问题。
然而,就测试而言,常见的解决方案是单独导出每个组件并单独测试。如果高级组件以某种方式组成它们,那么您真正需要测试的是它们是否正确组合,因为组件也是单独测试的。
有一种常见的分离模式&#34; smart&#34;和&#34;哑巴&#34;组件;哑组件只是简单地呈现他们给出的内容,并且非常容易进行单元测试。智能组件可以获取数据(例如,通过Ajax,或来自磁通存储),组合特定的哑组件,或做出其他的决定,&#34;并且可能更难以测试 - 但同样,由于哑组件已经过测试,理想情况下,您可以检查智能组件的行为是否正确并呈现正确的事物。
要使用您的示例,请Foo
来呈现<div><Bar><Baz /></Bar></div>
;它是一个智能组件,测试应该确保它完全呈现。然而,Bar
的工作是渲染孩子,并且更容易测试。
您还可以模拟组件with TestUtils.mockComponent
。
答案 1 :(得分:0)
结帐mochajs。此测试框架会覆盖import
/ require
,从而解决您的问题。
这确实意味着您的子组件需要编写为ECMA 6或NodeJS模块 - 但这实际上只是意味着它们需要位于不同的源文件中。