React新特性-Hooks之useContext(六)

useContext 跟class组件Context是一样的效果,Context能够允许数据跨域组件层级直接传递到任何的子组件身上。

详细请参考: React新特性-Context(一)

系列目录

如何使用useContext

//Page.js

// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
import React, { Component } from 'react';
import List from './List'

//导出ThemeContext,让后面的Item组件可以拿到
export const ThemeContext = React.createContext()

export default class Page extends Component {
  constructor(props) {
    super(props)
    this.state = {
      theme: 'red'
    }
  }
  onChangeTheme = (color) => {
    this.setState({ theme: color })
  }
  render() {
    const data = [
      {
        id: 1,
        text: '随随便便输入',
        color: 'yellow'
      }, {
        id: 2,
        text: '随便输入',
        color: 'blue'
      }
    ]
    // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
    // 无论多深,任何组件都能读取这个value值。
    return (
      <div>
        <ThemeContext.Provider value={{
          theme: this.state.theme,
          onChangeTheme: this.onChangeTheme
        }}>
          <List data={data} />
        </ThemeContext.Provider >
      </div>
    )
  }
}

// List.js
import React from 'react'
import Item from './Item'
export default function List(props) {
  return (
    <div> {
      props.data.map(i =>
        (
          <Item
            key={i.id}
            color={i.color}>
            {i.text}
          </Item>
        ))}
    </div>
  )
}

//Item.js
import React, { useContext } from 'react' //引入useContext
///导入Page中的ThemeContext对象
import { ThemeContext } from './Page'
export default function Item(props) {
  //拿到context数据
  const context = useContext(ThemeContext)
  return (
    <div>
      <p style={{ color: context.theme }}>
        {props.children}
        <button onClick={() => context.onChangeTheme(props.color)}>
          点击变色
      </button>
      </p>
      <ThemeContext.Consumer>
        {value => { console.log(value, 'render') }}
      </ThemeContext.Consumer>
    </div>
  )
}

此示例依照React新特性-Context(一),用useContext的方式来实现。

跟class组件中的Context有什么不同

Page.js代码中仅仅把创建出的Context对象导出去以供Item组件使用。然后使用useContext来拿到Context里面的值。

相比较React新特性-Context(一)的代码大致Page.js和List.js代码都没有变化,只是List改为函数组件。到了Item.js中,改为函数组件,由于函数组件并没有contextType不能像class组件中这样使用Item.contextType = ThemeContext,所以引入useContext函数。利用useContext的参数传入ThemeContext对象来拿到Context的值。

<ThemeContext.Consumer>
  {value => { console.log(value, 'render') }}
</ThemeContext.Consumer>

这里ThemeContext.Consumer的方式一样适用,并未做任何改变。


文章作者: jackie chen
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 jackie chen !
评论
 上一篇
React新特性-Hooks之useRef(七) React新特性-Hooks之useRef(七)
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。 系列目录 React新特性-Context(一) React新
2019-07-23
下一篇 
React新特性-Hooks之useEffect和useLayoutEffect(五) React新特性-Hooks之useEffect和useLayoutEffect(五)
Effect Hook 可以让你在函数组件中执行副作用操作,类似于class组件中的componentDidMount,componentDidUpdate和componentWillUnmount这三种生命周期函数的组合 系列目录 R
2019-07-21
  目录