组件可以组合到一块儿去用。之前在 App 组件的显示里用了 h2 元素,现在我们把它单独定义成一个叫 Header 的组件。然后在 App 里用一下 Header 这个组件,这样 App 就是 Header 组件的爸爸(Parent),Header 是 App 的儿子(Child)。爸爸给儿子可以传递数据,儿子在显示的时候可以使用这些数据,传递的数据叫属性(Props)。在儿子那里可以通过 this.props 得到传递的属性的值。
把 App.js 改造成下面这样:
import React, { Component } from 'react' class Header extends Component { render () { return ( <h2 onClick={ () => this.props.changeHeader() }> { this.props.header } </h2> ) } } class App extends Component { state = { header: 'ninghao.net' } changeHeader = () => { this.setState({ header: '😄' }) } render () { return ( <Header changeHeader={ this.changeHeader } header={ this.state.header } /> ) } } export default App
在 App 组件里,用了 Header 组件,用的时候 App 给 Header 传递了两件东西(Props),一个叫 changeHeader,还有一个是 header。在 Class 类型的组件里,可以用 this.props 访问到传递过来的属性。比如在 Header 组件里,可以用 this.props.changeHeader,还有 this.props.header 得到它爸爸也就是 App 组件传递过来的 changeHeader 还有 header 的值。
我们在 Header 组件的显示里的 h2 这个元素上,绑定了一个点击事件,发生事件,执行从它爸爸传递过来的 changeHeader 来处理事件。点击页面上显示的标题以后,会把标题变成一个 😄 表情。这个技巧以后经常会用到。儿子只管提出要求,具体执行全靠老爸。
事件对象
儿子:“爸,你看有人点我的标题(h2)了,用下你的 changeHeader ,你看着办吧。”,老爸:“好的,不过我可能需要事件对象(event),你把它给我传递过来。”
如果老爸那里的事件处理方法需要用到事件对象,在儿子那里使用的时候可以把 event 作为参数传递过去。
<h2 onClick={ (event) => this.props.changeHeader(event) }> { this.props.header } </h2>
爸爸这里,可以在事件处理里面添加 event 参数:
changeHeader = (event) => { this.setState({ header: '😄' }) console.log(event) }
其它参数
儿子在用它老爸那里传递过来的事件处理的时候,除了可以传递 event 对象,也可以传递额外的参数。
像这样改造一下 Header 组件:
class Header extends Component { state = { emoji: '👪' } render () { return ( <h2 onClick={ (event) => this.props.changeHeader(event, this.state.emoji) }> { this.props.header } </h2> ) } }
再去改造一下老爸那里的事件处理:
changeHeader = (event, emoji) => { this.setState({ header: emoji }) console.log(event, emoji) }
现在,点击了 Header 组件里的标题元素,会触发执行它老爸那里的 changeHeader 去修改标题。标题的内容会是 Header 里的 emoji 这个 state 的值。
现在的 App.js 整体是这样的:
import React, { Component } from 'react' class Header extends Component { state = { emoji: '👪' } render () { return ( <h2 onClick={ (event) => this.props.changeHeader(event, this.state.emoji) }> { this.props.header } </h2> ) } } class App extends Component { state = { header: 'ninghao.net' } changeHeader = (event, emoji) => { this.setState({ header: emoji }) console.log(event, emoji) } render () { return ( <Header changeHeader={ this.changeHeader } header={ this.state.header } /> ) } } export default AppReact