14. react - context

1. react 中的 context 使用了生产者消费者模式 【Provider和Customer模式】。

2. 可以在顶层的Provider中传入value,在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context

复制代码
// 1. context.js 中
import React from 'react'

const ThemeContext = React.createContext({
    theme: 'dark',
    toggle: () => {}, //向上下文设定一个回调方法
});
// const ThemeContext = React.createContext('light');

export default ThemeContext

// 2. index.js 中
import ThemeContext from './context'
import Content from './Toolbar'

const themes = {
  dark: 'dark',
  light: 'light'
}
// //运行APP
class App extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = () => { //设定toggle方法,会作为context参数传递
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    this.state = {
      theme: themes.light,
      toggle: this.toggle,
    };
  }

  render() {
    //state包含了toggle方法
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
)

// 3. 中间组件 Toolbar.js
import React from 'react'
import Button from './ThemeButton'

export default class Toolbar extends React.Component{
    constructor (props) {
        super(props)
    }

    render () {
        return (
            <div>
                <Button />
            </div>
        )
    }
    
}

// 4. 子组件 Button.js
import React from 'react'
import ThemeContext from './context'

class Button extends React.Component {
    constructor (props) {
        super(props)
    }

    render () {
      // context.Consumer 中必须是一个函数式组件。这个函数接收当前的 context 值,返回一个 React 节点。
return ( <ThemeContext.Consumer> {({theme, toggle}) => ( <button onClick={toggle} style={{backgroundColor: theme}}> {theme} </button> )} </ThemeContext.Consumer> ) } }
复制代码

3. 如何使用 this.context: 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你能在任何生命周期中使用 this.context

复制代码
import React from 'react'
import ThemeContext from './utils'

class Button extends React.Component {
    constructor (props) {
        super(props)
    }

    render () {
        console.log(this.context, "BBBBBBBBBBBB")
        return (
            <ThemeContext.Consumer>
                {({theme, toggle}) => (
                <button
                    onClick={toggle}
                    style={{backgroundColor: theme}}>
                    {theme}
                </button>
                )}
            </ThemeContext.Consumer>
        )
    }
}

Button.contextType = ThemeContext  //调用后可以在 Button 的组件的类中使用this.context

export default Button
复制代码

4. 那些生命周期中可以使用 this.context

constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)

复制代码
import React from 'react'
import ThemeContext from './utils'

class Button extends React.Component {
    constructor (props, context) {
        super(props, context)
        console.log(context)
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log(nextContext, "componentWillReceiveProps  context")
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log(nextContext, "shouldComponentUpdate  context")
    }


    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log(nextContext, "componentWillUpdate  context")
    }


    componentDidUpdate(prevProps, prevState, prevContext) {
        console.log(prevContext, "componentDidUpdate  context")
    }

    render () {
        console.log(this.context, "BBBBBBBBBBBB")
        return (
            <ThemeContext.Consumer>
                {({theme, toggle}) => (
                <button
                    onClick={toggle}
                    style={{backgroundColor: theme}}>
                    {theme}
                </button>
                )}
            </ThemeContext.Consumer>
        )
    }
}

Button.contextType = ThemeContext

export default Button
复制代码

 

5. React context的局限性

1. 在组件树中,如果中间某一个组件 ShouldComponentUpdate returning false 了,会阻碍 context 的正常传值,导致子组件无法获取更新。
2. 组件本身 extends React.PureComponent 也会阻碍 context 的更新。

 

posted @   monkey-K  阅读(155)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示