如果我们在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 方法。但这个问题的目的是解决这个问题而不这样做。
答案 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 });
它返回包含新道具的组件的克隆。