分类:
父子组件通信
无论父组件传递是props还是state,子组件都是通过props接收
import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
{/* <Son name={this.state.name}/> */}
<Son {...this.state}/>
</Fragment>
)
}
}
export default Father
import React, {Component,Fragment} from 'react'
class Son extends Component{
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<p>{this.props.name}</p>
</Fragment>
)
}
}
export default Son
子父组件通信
父组件传递方法给子组件,子组件调用父组件传递过来的方法
注意: 自己的状态自己更改
import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
changeName=( val )=>{
this.setState({
name:val
})
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son changeName={this.changeName}/>
<p>name: { this.state.name }</p>
</Fragment>
)
}
}
export default Father
import React, {Component,Fragment} from 'react'
class Son extends Component{
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<button onClick={()=>{this.props.changeName('lisi')}}>改名</button>
</Fragment>
)
}
}
export default Son
非父子组件通信
ref链
1. ref = ‘xxx’ this.refs.xxx
2. ref = { el => this.xxx = el } this.xxx 【 推荐 】
import React, {Component,Fragment} from 'react'
import Son from './Son'
import Girl from './Girl'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
kick=()=>{
console.log(this)
this.son.change()
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son ref={ el => this.son = el }/>
<hr/>
<Girl ref={ el => this.girl = el} kick={this.kick}/>
</Fragment>
)
}
}
export default Father
import React, {Component,Fragment} from 'react'
class Son extends Component{
constructor(){
super()
this.state={
flag:false
}
}
change = () => {
this.setState({
flag:!this.state.flag
})
}
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
{ this.state.flag && <p>(╥╯^╰╥)(╥╯^╰╥)(╥╯^╰╥)</p>}
</Fragment>
)
}
}
export default Son
import React, {Component,Fragment} from 'react'
class Girl extends Component{
render(){
return(
<Fragment>
<p> 这里是girl组件 </p>
<button onClick={this.props.kick}>揍</button>
</Fragment>
)
}
}
export default Girl
跨组件通信
context
使用流程
- 创建上下文 React.createContext()
- 使用上下文包裹目标组件的父组件
- 在目标组件中先定义一个静态属性 static contextType = MoneyContext
- 通过 this.context来使用数据
// 定义一个上下文
import React from 'react'
export const Context= React.createContext()
import React, {Component,Fragment} from 'react'
import Father from './Father'
import {Context} from './context'
class GrandFather extends Component{
constructor(){
super()
this.state={
name:'Shirley'
}
}
render(){
return(
<Fragment>
<p>这里是爷爷组件</p>
<Context.Provider value={this.state.name}>
{/* 这里用解构会报错 */}
<Father/>
</Context.Provider>
</Fragment>
)
}
}
export default GrandFather
import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son/>
</Fragment>
)
}
}
export default Father
import React, {Component,Fragment} from 'react'
import { Context } from './context'
class Son extends Component{
static contextType = Context
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<p>爷爷传过来的数据:{this.context}</p>
</Fragment>
)
}
}
export default Son
多组件状态共享
Flux
redux
mobx ( 阿里 )
父组件与子组件通信
- 父组件将自己的状态传递给子组件,子组件当做属性来接收,当父组件更改自己状态的时候,子组件接收到的属性就会发生改变
- 父组件利用
ref
对子组件做标记,通过调用子组件的方法以更改子组件的状态,也可以调用子组件的方法…
子组件与父组件通信 - 父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过
this.props
接收到父组件的方法后调用。
跨组件通信
在react没有类似vue中的事件总线来解决这个问题,我们只能借助它们共同的父级组件来实现,将非父子关系装换成多维度的父子关系。react提供了context
api来实现跨组件通信, React 16.3之后的context
api较之前的好用。
实例,使用context
实现购物车中的加减功能
// counterContext.js
import React, { Component, createContext } from 'react'
const {
Provider,
Consumer: CountConsumer
} = createContext()
class CountProvider extends Component {
constructor () {
super()
this.state = {
count: 1
}
}
increaseCount = () => {
this.setState({
count: this.state.count + 1
})
}
decreaseCount = () => {
this.setState({
count: this.state.count - 1
})
}
render() {
return (
<Provider value={{
count: this.state.count,
increaseCount: this.increaseCount,
decreaseCount: this.decreaseCount
}}
>
{this.props.children}
</Provider>
)
}
}
export {
CountProvider,
CountConsumer
}
// 定义CountButton组件
const CountButton = (props) => {
return (
<CountConsumer>
// consumer的children必须是一个方法
{
({ increaseCount, decreaseCount }) => {
const { type } = props
const handleClick = type === 'increase' ? increaseCount : decreaseCount
const btnText = type === 'increase' ? '+' : '-'
return <button onClick={handleClick}>{btnText}</button>
}
}
</CountConsumer>
)
}
// 定义count组件,用于显示数量
const Count = (prop) => {
return (
<CountConsumer>
{
({ count }) => {
return <span>{count}</span>
}
}
</CountConsumer>
)
}
// 组合
class App extends Component {
render () {
return (
<CountProvider>
<CountButton type='decrease' />
<Count />
<CountButton type='increase' />
</CountProvider>
)
}
}
复杂的非父子组件通信在react中很难处理,多组件间的数据共享也不好处理,在实际的工作中我们会使用flux、redux、mobx来实现