非父子通信-状态提升-发布订阅者模式-context状态树传参(React)

收藏

(1)状态提升(中间人模式)

React中的状态提升概括来说,就是将多个组件需要共享的状态提升到他们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件

import React, { Component } from 'react'
import axios from 'axios'
import '../01-base/css/02-卖座.css'
// 受控组件
class FilmItem extends Component {
  render() {
    console.log(this.props)
    let {name,poster,grade,synopsis} = this.props
    return (
      <div className='filmItem' onClick={()=>{
        this.props.onEvent(synopsis)
      }}>
        <img src={poster} alt=""/>
        <h4>{name}</h4>
        <div>观众评分:{grade}</div>
      </div>
    )
  }
}
class FilmDetail extends Component {
    render() {
        let {detail} = this.props
      return (
        <div className='filmDetail'>
         {detail}
        </div>
      )
    }
  }
export default class App extends Component {
    constructor(props) {
        super(props)
        this.state = {
            filmList:[],
            detail:''
        }
        axios.get(`/test.json`)
        .then(res=>{
            console.log(res.data.data.films)
            this.setState({
                filmList:res.data.data.films
            })
        })
    }
  render() {
    return (
      <div>
        {
            this.state.filmList.map(item=>{
                return(<FilmItem key={item.filmId} {...item} onEvent={(synopsis)=>{
                    this.setState({
                        detail:synopsis
                    })
                }}></FilmItem>)
            })
        }
        <FilmDetail detail={this.state.detail}/>
      </div>
    )
  }
}

(2)发布订阅者模式

import React, { Component } from 'react'
import axios from 'axios'
import '../01-base/css/02-卖座.css'
var bus = {
    list: [],
    // 订阅
    subscribe: function (callback) {
        this.list.push(callback)
    },
    // 发布
    publish: function (text) {
        this.list.forEach(callback => {
            callback && callback(text)
        })
    }
}
// 受控组件
class FilmItem extends Component {
    render() {
        console.log(this.props)
        let { name, poster, grade, synopsis } = this.props
        return (
            <div className='filmItem' onClick={() => {
                bus.publish(synopsis)
            }}>
                <img src={poster} alt="" />
                <h4>{name}</h4>
                <div>观众评分:{grade}</div>
            </div>
        )
    }
}
class FilmDetail extends Component {
    constructor() {
        super()
        this.state = {
            detail: ''
        }
        bus.subscribe((detail) => {
            this.setState({
                detail: detail
            })
        })
    }
    render() {
        return (
            <div className='filmDetail'>
                {this.state.detail}
            </div>
        )
    }
}
export default class App extends Component {
    constructor(props) {
        super(props)
        this.state = {
            filmList: [],
        }
        axios.get(`/test.json`)
            .then(res => {
                console.log(res.data.data.films)
                this.setState({
                    filmList: res.data.data.films
                })
            })
    }
    render() {
        return (
            <div>
                {
                    this.state.filmList.map(item => {
                        return (<FilmItem key={item.filmId} {...item}></FilmItem>)
                    })
                }
                <FilmDetail />
            </div>
        )
    }
}

(3)context状态树传参(跨级通讯的一种方案)

import React, { Component } from 'react'
import axios from 'axios'
import '../01-base/css/02-卖座.css'
const GlobalContext = React.createContext()//创建context对象
// 受控组件
class FilmItem extends Component {
    render() {
        let { name, poster, grade, synopsis } = this.props
        return (
            <GlobalContext.Consumer>
                {
                    (value) => {
                        return (
                            <div className='filmItem' onClick={() => {
                               value.callback(synopsis)
                            }}>
                                <img src={poster} alt="" />
                                <h4>{name}</h4>
                                <div>观众评分:{grade}</div>
                            </div>
                        )
                    }
                }
            </GlobalContext.Consumer>
        )
    }
}
class FilmDetail extends Component {
    constructor() {
        super()
        this.state = {
            detail: ''
        }
    }
    render() {
        return (
            <GlobalContext.Consumer>
                {(value) => {
                    console.log(value);
                    return (
                        <div className='filmDetail'>
                            {value.synopsis}
                        </div>
                    )
                }}
            </GlobalContext.Consumer>
        )
    }
}
export default class App extends Component {
    constructor(props) {
        super(props)
        this.state = {
            filmList: [],
            synopsis: ''
        }
        axios.get(`/test.json`)
            .then(res => {
                this.setState({
                    filmList: res.data.data.films
                })
            })
    }
    render() {
        return (
            <GlobalContext.Provider value={{
                synopsis: this.state.synopsis,
                callback: (value) => {
                    this.setState({
                        synopsis: value
                    })
                }
            }
            }>
                <div>
                    {
                        this.state.filmList.map(item => {
                            return (<FilmItem key={item.filmId} {...item}></FilmItem>)
                        })
                    }
                    <FilmDetail />
                </div>
            </GlobalContext.Provider >
        )
    }
}


评论(

您还未登录,请先去登录
表情
查看更多

相关作者

  • 获取点赞0
  • 文章阅读量264

相关文章

联系小鹿线

咨询老师

咨询老师

扫码下载APP