首先使用 vite 新建一个 React 项目。
React版本:18.0.0
父子通信 props + 函数
我们改写一下 App.jsx ,将个人信息的相关参数逐一传递给 UserInfoCard.jsx 组件,代码如下:
export default class App extends Component {
constructor() {
super()
this.state = {
myInfo: {
avatarURL: 'https://p26-passport.byteacctimg.com/img/user-avatar/76a815f3450e3c836f11f32a058444d8~300x300.image',
name: 'leyili',
occupation: 'FED',
motto: '生活不奖赏心血来潮。'
}
}
}
render() {
return (
<div>
<UserInfoCard
avatarURL={this.state.myInfo.avatarURL}
name={this.state.myInfo.name}
occupation={this.state.myInfo.occupation}
motto={this.state.myInfo.motto}
/>
</div>
)
}
}
UserInfoCard 组件来接收这些参数,要使用 props ,则必须写 constructor ,并且在其中必须有 super ,代码如下:
import React, { Component } from 'react'
export default class UserInfoCard extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div className='card-wrapper'>
<img className='avatar' src={this.props.avatarURL} alt='avatar' />
<div>姓名:{this.props.name}</div>
<div>职业:{this.props.occupation}</div>
<div>座右铭:{this.props.motto}</div>
</div>
)
}
}
这是基本的父组件传递参数给子组件,那如果子组件想要变更父组件传递的信息应该如何做?
也是要靠父组件主动给子组件传递参数,只不过这次需要传递的是一个函数。
首先改写一下 UserInfoCard.jsx
import React, { Component } from 'react'
export default class UserInfoCard extends Component {
constructor(props) {
super(props)
}
change = () => {
this.props.changeOccupation('在线炒粉')
}
render() {
return (
<div className='card-wrapper'>
<img className='avatar' src={this.props.avatarURL} alt='avatar' />
<div>姓名:{this.props.name}</div>
<div>职业:{this.props.occupation}</div>
<div>座右铭:{this.props.motto}</div>
<button onClick={this.change}>更换职业</button>
</div>
)
}
}
我们新加了一个按钮,并为其添加了一个点击事件,当点击事件触发后就调用 props 中的 changeOccupation 函数并传递一个新的职业名称给该函数。
好了,接下来我们看父组件该如何定义这个函数。
import React, { Component } from 'react'
import UserInfoCard from './UserInfoCard'
export default class App extends Component {
constructor() {
super()
this.state = {
myInfo: {
avatarURL: 'https://p26-passport.byteacctimg.com/img/user-avatar/76a815f3450e3c836f11f32a058444d8~300x300.image',
name: 'leyili',
occupation: 'FED',
motto: '生活不奖赏心血来潮。'
}
}
}
// 函数处理,更新 state
changeOccupation = (newVal) => {
this.setState({
myInfo: {
...this.state.myInfo,
occupation: newVal
}
})
}
render() {
return (
<div>
<UserInfoCard
avatarURL={this.state.myInfo.avatarURL}
name={this.state.myInfo.name}
occupation={this.state.myInfo.occupation}
motto={this.state.myInfo.motto}
// 新添加的参数,传递一个函数给子组件
changeOccupation={this.changeOccupation}
/>
</div>
)
}
}
爷孙通信
两层父子通信
暂时没想到好的例子,我们强行把座右铭做成一个组件好了。
import React, { Component } from 'react'
export default class Motto extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>座右铭:{this.props.motto}</div>
)
}
}
然后 UserInfoCard 稍微做一下改动:
import React, { Component } from 'react'
import Motto from './Motto'
export default class UserInfoCard extends Component {
constructor(props) {
super(props)
}
change = () => {
this.props.changeOccupation('在线炒粉')
}
render() {
return (
<div className='card-wrapper'>
<img className='avatar' src={this.props.avatarURL} alt='avatar' />
<div>姓名:{this.props.name}</div>
<div>职业:{this.props.occupation}</div>
{/* <div>座右铭:{this.props.motto}</div> */}
<Motto motto={this.props.motto} />
<button onClick={this.change}>更换职业</button>
</div>
)
}
}
Context
官网对 Context 的介绍: reactjs.org/docs/contex…
首先我们新建一个 myContext.jsx 文件:
import React from 'react'
export const myContext = React.createContext()
然后在需要用到的地方去引入,在 App.jsx 中使用 Provider:
import React, { Component } from 'react'
import UserInfoCard from './UserInfoCard'
import { myContext } from './myContext'
export default class App extends Component {
constructor() {
super()
this.state = {
myInfo: {
avatarURL: 'https://p26-passport.byteacctimg.com/img/user-avatar/76a815f3450e3c836f11f32a058444d8~300x300.image',
name: 'leyili',
occupation: 'FED',
motto: '生活不奖赏心血来潮。'
}
}
}
changeOccupation = (newVal) => {
this.setState({
myInfo: {
...this.state.myInfo,
occupation: newVal
}
})
}
render() {
return (
<myContext.Provider value={{ motto: this.state.myInfo.motto }} >
<UserInfoCard
avatarURL={this.state.myInfo.avatarURL}
name={this.state.myInfo.name}
occupation={this.state.myInfo.occupation}
motto={this.state.myInfo.motto}
changeOccupation={this.changeOccupation}
/>
</myContext.Provider>
)
}
}
在 Motto.jsx 中使用 Consumer:
import React, { Component } from 'react'
import { myContext } from './myContext'
export default class Motto extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
console.log('this', this)
}
static contextType = myContext
render() {
return (
// <div>座右铭:{this.props.motto}</div>
// <div>座右铭:{this.context.motto}</div>
<myContext.Consumer>
{value => <div>座右铭:{value.motto}</div>}
</myContext.Consumer>
)
}
}
任意组件通信
其实就是使用状态管理库了,如 Redux、Mobx 。
我们下次再做介绍吧!