首页 文章

React:直接导入子组件而不是作为依赖项传入是不好的做法?

提问于
浏览
2

我可能在想这个,但我很好奇,如果直接导入子组件是关于耦合和测试的坏习惯 .

下面是一个简单的例子:

import Header from './header.jsx';

class Widget extends React.Component {
    render() {
        return (
            <div>
                <Header></Header>
                <div>{this.props.importantContent}</div>
            </div>
        )
    }
}

对我来说,看起来现在 WidgetHeader 之间存在耦合 . 关于测试,我没有看到在测试 Widget 组件时模拟 Header 组件的简单方法 .

其他更大的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这样的子组件 .

想法或其他想法?

2 回答

  • 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 注入

    如果要与props交互/将数据发送回父级,您还可以传递组件,而不仅仅是元素:

    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

    只要组件总是呈现相同的东西,它就可以直接呈现为子而不是父 .

    如果组件的所有其他部分保持不变,并且只有页眉可以在页面之间不同,那么您实际上可以将其实现为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)
    })
    

相关问题