反应。如何在道具上定义的组件内传递道具?

时间:2017-06-25 04:09:15

标签: reactjs

如果我们在React应用程序上有以下结构:

class BasePage extends React.Component {

    render() {
        return <div>
            {this.props.header}
            {/*<Header title={this.props.title} />*/}
        </div>
    }
}

BasePage.defaultProps = {
    header: <header>Base Page</header>
}

class Header extends React.Component {

    render() {
        return <header>
            <h1>{this.props.title}</h1>
        </header>
    }
}

class TestPage extends BasePage {
}

TestPage.defaultProps = {
    header: <Header />
}

class Root extends React.Component {

  render() {
    return <div>
            <TestPage
                title="Test Page Title"
            />
    </div>
  }
}

ReactDOM.render(
    <Root />,
    document.getElementById('root')
)

如果我们有一个常见组件,例如<Header />,我们可以像<Header title={this.props.title} />一样轻松传递title属性。

但是,如果将此组件定义为prop本身,我们如何在组件内传递道具?

例如,我们怎样才能做到:

{this.props.header title={this.props.title}}

那么它会正确呈现测试页面标题吗?

重要提示:我们可以覆盖Test组件中的 render 方法。但这个问题的目的是解决这个问题而不这样做。

2 个答案:

答案 0 :(得分:2)

首先,props are read-only和组件永远不应该更新它自己的props,所以像

这样的行
componentWillMount() {
    this.props.header = <header>Base Page</header>
}
不应该使用

defaultProps可以做我认为你想做的事情:

class BasePage extends React.Component {
    render() {
        return <div>
            {this.props.header}
            {/*<Header title={this.props.title} />*/}
        </div>
    }
}

BasePage.defaultProps = {
    header: <header>Base Page</header>
}

其次,inheritance is not often done in React。我并不是说不做你正在做的事情,而是采取read of the docs并看看是否有更简单的方法来实现相同的目标。

最后,在作为道具传递的组件上设置道具。有几种不同的方法可以做到这一点。

如果您通过Component而不是<Component />,则可以添加正常的道具:

ChildComponent = (props) => {
  const HeaderComponent = props.header
  return <HeaderComponent title="..." />
}

ParentComponent = () => <ChildComponent header={Header} />

你可以clone the element覆盖道具:

ChildComponent = (props) => {
  const HeaderComponent = React.cloneElement(props.header. { title: "..." })
  return <HeaderComponent />
}

ParentComponent = () => <ChildComponent header={<Header />} />

注意:为简洁起见,我使用了functional components instead of class components,但概念是相同的。

答案 1 :(得分:1)

这似乎是React.cloneElement的一个很好的用例。

React.cloneElement(this.props.header, { title: this.props.title });

它返回包含新道具的组件的克隆。