我可能在想这个,但我很好奇,如果直接导入子组件是关于耦合和测试的坏习惯。
下面是一个简单的例子:
import Header from './header.jsx';
class Widget extends React.Component {
render() {
return (
<div>
<Header></Header>
<div>{this.props.importantContent}</div>
</div>
)
}
}
对我而言,Widget
和Header
之间似乎存在耦合。关于测试,我在测试Header
组件时没有看到模拟Widget
组件的简单方法。
其他较大的React应用程序如何处理这样的案例?我应该将Header
作为道具传递吗?如果使用react-redux
,我可以使用下面的Connect
方法注入标头以减少样板。听起来好吗?
import { connect } from 'react-redux';
import Header from './header.jsx';
class Widget extends React.Component {
render() {
return (
<div>
{this.props.header}
<div>{this.props.importantContent}</div>
</div>
)
}
}
const mapStateToProps = state => {
return {
header: Header
}
}
export default connect(mapStateToProps)(Widget)
我感兴趣的是做社区一般做的事情。我看到一个解决方案是使用浅层渲染来测试组件的主要部分,而不是像Enzyme那样测试子组件。
思想或其他想法?
答案 0 :(得分:1)
将元素/组件作为道具传递是一个好主意。拥有默认道具也是一个好主意:
const Widget = ({
header = <div>Default Header.. </div>,
content = <div>Default Content.. </div>
}) =>
<div>
{header}
{content}
</div>
然后在你的应用中的其他地方:
<Widget header={<Header title="Foo" />} content="content from props" />
无需使用connect
如果你想与道具交互/将数据发送回父母,你也可以传递一个组件,而不仅仅是一个元素:
const Widget = ({
Header = props => <div>Default Header.. </div>,
Content = props => <div>Default Content.. </div>
}) =>
<div>
<Header />
<Content />
</div>
其他地方:
<Widget Header={Header} Content={props => <Content />} />
答案 1 :(得分:1)
只要组件始终呈现相同的内容,它就可以直接呈现为子项而不是父项。
如果Component的所有其他部分保持不变并且只有Header可以在页面之间有所不同,那么你实际上可以将它实现为HOC而不是将其作为道具传递
const MyCompFactory = ({CustomHeader = DefaultHeader}) => {
return class Widget extends React.Component {
render() {
return (
<div>
<CustomHeader/>
<div>{this.props.importantContent}</div>
</div>
)
}
}
}
并像
一样使用它const CustomComponent = MyCompFactory({CustomComponent: Header})
只要在您的情况下进行测试,您可以浅显示您的组件,然后搜索Header组件是否呈现类似
import Header from 'path/to/header'
const component = shallow(
<Widget {...customProps}/>
)
test('test' , () => {
expect(component.find(Header).exists()).toBe(true)
})