组合vs继承
React 有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用。
props.children
有些组件无法提前知晓它们子组件的具体内容。在 Sidebar(侧边栏)和 Dialog(对话框)等展现通用容器(box)的组件中特别容易遇到这种情况。
我们建议这些组件使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中:
class SideBarItems extends React.Component {render(){return (<ul><li>首页</li><li>用户管理</li><li>商品管理</li><li>内容管理</li></ul>)}}class SideBar extends React.Component {constructor(props){super(props);}render(){return (<div>{this.props.children}</div>)}}class Content extends React.Component {render(){return (<div>这是内容部分</div>)}}class FootBar extends React.Component {render(){return (<div>这是底部部分</div>)}}class BaseLayout extends React.Component {constructor(props){super(props);}render(){return (<div>{/*props.children是默认熟悉,指当前组件标签的内容部分*/}{this.props.children}</div>)}}class HelloWorld extends React.Component {render(){return (<div>{/*类似于vue的插槽slot */}<BaseLayout><SideBar><SideBarItems/></SideBar><Content/><FootBar/></BaseLayout></div>)}}// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.ReactDOM.render(<App />, document.getElementById("root"));
具名插槽
少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用children,而是自行约定:将所需内容传入 props,并使用相应的 prop。
function SplitPane(props) {return (<div className="SplitPane"><div className="SplitPane-left">{props.left}</div><div className="SplitPane-right">{props.right}</div></div>);}function App() {return (<SplitPaneleft={<Contacts />}right={<Chat />} />);}
特例关系
function Dialog(props) {return (<FancyBorder color="blue"><h1 className="Dialog-title">{props.title}</h1><p className="Dialog-message">{props.message}</p>{props.children}</FancyBorder>);}class SignUpDialog extends React.Component {constructor(props) {super(props);this.handleChange = this.handleChange.bind(this);this.handleSignUp = this.handleSignUp.bind(this);this.state = {login: ''};}render() {return (<Dialog title="Mars Exploration Program"message="How should we refer to you?"><input value={this.state.login}onChange={this.handleChange} /><button onClick={this.handleSignUp}>Sign Me Up!</button></Dialog>);}handleChange(e) {this.setState({login: e.target.value});}handleSignUp() {alert(`Welcome aboard, ${this.state.login}!`);}}

