react - 09.useContext / React.createContext

100 阅读2分钟

1.useContext的作用:

Context是一种对其所包含组件树提供全局共享数据的技术,而useContext是在React Hooks中对Context进行的封装,他可以帮助我们跨越组件层级直接传递数据,实现数据共享,让使用变得更简单

假设我们在根组件嵌入子组件A,在子组件A嵌入孙组件B,我们想直接通过根组件向孙组件B传递参数,我们就可以使用useContext来实现

2.useContext的基础语法和参数说明:

const AppContext = React.createContext(initialValue);

const MyContext = useContext(AppContext);

initialValue参数是context的初始值,useContext的返回值有如下两种:

MyContext.Provider:提供者,是React组件,使用Provider标签包裹后的组件,自身及其后代组件都可以访问MyContext的值

MyContext.Consumer:消费者,是React组件,使用Consumer包裹后,可以使用render props(回调函数)的方式渲染内容,获取MyContext的值

对于<MyContext.Provider value={ [keyName]:'keyValue' } />需要注意此处属性名称必须为value,并且值为一个键值对对象,如:

<MyContext.Provider value={ userName:'xiaoming' }>

</MyContext.Provider>

3.例子:

import React, { useContext } from 'react';
const AppContext = React.createContext({} as any)
const C = () => {
  const appContext = useContext(AppContext)
  const handleChange = () => {
    console.log(appContext)
  }
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#ccc',
      margin: '50px',
      padding: '50px'
    }}>
      <div>子组件C</div>
      <button type="button" onClick={handleChange}>change</button>
    </div>
  )
}
const B = () => {
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#999',
      margin: '50px'
    }}>
      <div>子组件B</div>
      <C></C>
    </div>
  )
}
const A = () => {
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#666',
      margin: '50px'
    }}>
      <div>子组件A</div>
      <B></B>
    </div>
  )
}
const App = () => {
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      border: '1px solid #000',
      margin: '50px'
    }}>
      <div>通过根组件传参给子组件C</div>
      <AppContext.Provider value={{
        userName: "xiaoming",
        userAge: 22,
        userSex: true
      }}>
        <A></A>
      </AppContext.Provider>
    </div>
  )
}
export default App

React支持并行使用多个useContext,示例如下:

import React, { useContext, useState } from 'react';
const AppContext = React.createContext({} as any)
const ThemeContext = React.createContext({} as any)
const C = () => {
  const appContext = useContext(AppContext)
  const themeContext = useContext(ThemeContext)
  const handleChange = () => {
    console.log(appContext.data)
    console.log(themeContext.color)
  }
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#ccc',
      margin: '50px',
      padding: '50px'
    }}>
      <div>子组件C</div>
      <div>主题:{themeContext.color}</div>
      <button type="button" onClick={handleChange}>change</button>
    </div>
  )
}
const B = () => {
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#999',
      margin: '50px'
    }}>
      <div>子组件B</div>
      <C></C>
    </div>
  )
}
const A = () => {
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      backgroundColor: '#666',
      margin: '50px'
    }}>
      <div>子组件A</div>
      <B></B>
    </div>
  )
}
const App = () => {
  const [data, setData] = useState({
    userName: "xiaoming",
    userAge: 22,
    userSex: true
  })
  const [theme, setTheme] = useState('red')
  return (
    <div style={{
      width: 'auto',
      float: 'left',
      border: '1px solid #000',
      margin: '50px'
    }}>
      <div>通过根组件传参给子组件C</div>
      <AppContext.Provider value={{ data: data }}>
        <ThemeContext.Provider value={{ color: theme }}>
          <A></A>
        </ThemeContext.Provider>
      </AppContext.Provider>
    </div>
  )
}
export default App

例子2:

import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext({} as any)
// 通过useContext获取
const B = () => {
  const getTheme = useContext(ThemeContext)
  return (
    <div>{getTheme.color}</div>
  )
}
// 通过Consumer获取
const C = () => {
  return (
    <div>
      <ThemeContext.Consumer>
        {
          x => <div>{x.color}</div>
        }
      </ThemeContext.Consumer>
    </div>
  )
}
const App = () => {
  const [theme, setTheme] = useState('red')
  const handleClick = () => {
    setTheme('blue')
  }
  return (
    <div>
      <button onClick={handleClick}>change</button>
      <ThemeContext.Provider value={{color:theme}}>
        <B></B>
        <C></C>
      </ThemeContext.Provider>
    </div>
  )
}
export default App