学习下react的hook(useContext)

250 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

前言

前面2篇文章我们讲了react的useState,和useEffect

文章地址:

咱们今天来看看react的其它常用hook,useContext

Context

在讲useContext之前,我们要先来讲讲Context,因为它们是配合使用的。

Context是解决组件之间数据共享的,同理useContext也是解决组件数据通信的hook。

正常一般组件数据通信通过props就能解决,但是如果层级过深,props就得一直传下去,不方便。

所以就有了Context。这个不管你层级多深,只要你在顶层定义了共享的数据,在哪层的子孙组件都能访问到这个共享数据。

下面这个例子,如果正常使用props,那么就要一层一层从CompA传到CompD

function CompA () {
  const [text] = useState('答案cp3')
  return (
    <CompB text={text}></CompB>
  )
}
function CompB (props) {
  return (
    <CompC text={props.text}></CompC>
  )
}
function CompC (props) {
  return (
    <CompD text={props.text}></CompD>
  )
}
function CompD (props) {
  return (
    <div>{props.text}</div>
  )
}

那么来看看如果使用Context该怎么写?

要先定义context对象,括号内是初始值。

const textContext = React.createContext('')

然后把textContext导出标签 ProviderConsumer,用Provider标签包裹着CompB。 这时候可以提供value,会覆盖createContext定义的初始值。

如果不使用Provider标签,则createContext的初始值会生效。

接着使用Consumer使用包裹着CompD, 这个Consumer是在函数组件使用的。内部返回一个函数,参数就是共享的value。

const { Provider, Consumer } = textContext

function CompA () {
  return (
    <Provider value={'答案cp3'}>
      <CompB></CompB>
    </Provider>
  )
}

function CompB () {
  return (
    <CompC></CompC>
  )
}

function CompC () {
  return (
    <CompD></CompD>
  )
}
function CompD () {
  return (
    <Consumer>
      {value => value}
    </Consumer>
  )
}

这样实现,CompB和CompC就不用一层一层写props了。

如果你使用的是class组件,则可以不使用Consumer,代码如下:

class CompD extends React.Component {
  static contextType = textContext
  render () {
    return (
      <div>{this.context}</div>
    )
  }
}

要定义个静态对象contextType, render函数this.context就是定义的value。

上面说的只是获取,那怎么修改呢?

如果你要修改context的内容,你定义个方法,传入然后对应的组件里调用,就可以修改了。

代码如下:

function CompA () {
  const [text, setText] = useState('hello world')
  return (
    <Provider value={{ text, setText }}>
      <CompD></CompD>
    </Provider>
  )
}
class CompD extends React.Component {
  static contextType = textContext
  clickFn = () => {
    this.context.setText('答案cp3')
  }

  render () {
    return (
      <div onClick={this.clickFn}>{this.context.text}</div>
    )
  }
}

好,context的知识已经学完了。下面来看看useContext

useContext

useContext其实相当于上面的说的Consumer或者静态方法contextType

使用了useContext就不用在函数组件中使用Consumer了。

返回的是顶层定义的数据。

我用上面的例子改写一下:

function CompA () {
  const [text, setText] = useState('hello world')
  return (
    <Provider value={{ text, setText }}>
      <CompD></CompD>
    </Provider>
  )
}
function CompD () {
  const { text, setText } = useContext(textContext)
  return (
    <div onClick={() => setText('答案cp3')}>{text}</div>
  )
}

这样看起来useContext是不是更简洁一些?