react组件化通信-ContextApi的使用细节

react组件化通信-ContextApi的使用细节

常见问题
  • context现在不常见了,不建议使用?

    现在的开发,context不常见是对的,但是不是不建议使用,存在即合理,如redux源码就是有用到这个思想的,react-router也是有用到的

    但是尽量少用是真的,因为消耗的性能是相对比较大的,因为一旦改变所有的有使用的子组件都会进行渲染更新,这个还是相对比较消耗性能的,所以要慎重!并不是不用

  • context与redux

    redux主要做的是数据共享,而context目标的跨层级传递

    context涉及到祖孙组件的关系,而redux不涉及这个,组件之间没有明显的层级关系

contextAPI

context的定义就是组件跨层级通讯,思想是有生产者和消费者的概念,生产者定义传递给子组件的数据,子组件作为消费者只要根据指定的设置contextType或者useContext就可以接收到这个数据,无论组件之间跨越了多少层级都可以传递数据

最常见使用到的场景就是网站的一件换肤

// 创建context对象与生产者消费者对象
import React from 'react'
export const ThemeContext = React.createContext({themeColor:'skyblue'})
export const ThemeProvider = ThemeContext.Provider
export const ThemeConsumer = ThemeContext.Consumer

// 生产者使用 
const Index = ()=>{
    return (
    return (
        <div>
          <button onClick={changeColor}>一键换肤</button>
          <ThemeProvider value={theme}>
            <UseContextPage />
            <ContextTypePage />
          </ThemeProvider>
        </div>
      )
}

// 使用contextType接收context对象
class Index extends Component {
  // 类组件固定写法 这个 静态属性 名字不能改 赋值的就是提供Provider的那个对象
  static contextType = ThemeContext 
  render() {
    const { themeColor } = this.context
    return (
      <div className={themeColor}>换肤功能已经上线</div>
    )
  }
}

// 使用useContext接收context对象
const Index = () => {
  // 使用hooks接收 赋值的就是提供Provider的那个对象
  const { themeColor } = useContext(ThemeContext)
  return (
    <div className={themeColor}>换肤功能已经上线</div>
  )
}

// 使用Consumer接收context对象
class Index extends Component {
  render() {
    return (
      <div>
        <ThemeConsumer>
          {(themeContext) => (<div className={themeContext.themeColor}>换肤功能已经上线</div>)}
        </ThemeConsumer>
      </div>
    )
  }
}
contextType与useContext与consumer的区别
  • contextType方式只能用在类组件中

  • useContext只能用在函数组件和自定义hooks中

  • contextType只能订阅单一的context来源,useContext可以读取多个

    // contextType
    class Index extends Component {
      static contextType = ThemeContext 
      static contextType = UserContext//后写的会覆盖先写的
    }
    // useContext
    const Index = () => {
      // 两个都会生效
      const { themeColor } = useContext(ThemeContext)
      const { user } = useContext(UserContext)
    }
    
  • 在类组件中如果想接收多个context源,则可以使用 consumer 来接收

    真实项目中不会这么用,但是可以实现的

    class Index extends Component {
      render() {
        return (
          <div>
            <ThemeConsumer>
              {(themeContext) => (<div className={themeContext.themeColor}>换肤功能已经上线</div>)}
              <UserConsumer>
                {userContext => <p>user:{userContext.user}</p>
              </UserConsumer>
            </ThemeConsumer>
          </div>
        )
      }
    }
    
  • consumer没有那么多限制了,可以用在类组件也可以使用也可以在函数组件中使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值