最近在学习React-Hooks,顺便记一下笔记,有错误之处还请指正,共勉。
Context
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
React组件中,数据是通过 props
属性自上而下(由父及子)进行传递的:
当一些数据需要全局用到的业务场景下:例如切换用户登录信息、切换语言、切换主题,props层层传递数据就显得复杂繁琐。Context
提供了一种共享数据的方式,不用通过props层层传递数据,在任意一级组件中都可以直接获取到需要的数据。
创建一个Context对象
import React, { useState, createContext } from 'react';
const CountContext = createContext();
每个 Context
对象都会返回一个 Provider
React 组件,并接收一个value值,传递给Consumer
组件。
若<Consumer>没有对应的Provider传值
,则使用createContext(defaultValue)
默认值。
创建一个函数组件App
和一个类组件子组件Child
:
import React, { Component, useState, createContext } from 'react';
const CountContext = createContext();
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button
type='button'
onClick={() => {
setCount(count + 1)
}}
>
addCount:{count}
</button>
<CountContext.Provider value={count}>
<Child />
</CountContext.Provider>
</div>
)
}
class Child extends Component {
render() {
return(
<CountContext.Consumer>
{ count => <h1>count: { count }</h1> }
</CountContext.Consumer>
)
}
}
export default App;
执行程序,点击按钮,0会自增加1。显示addCount:1 count: 1
使用contextType属性
官网中的解释:挂载在 class
上的 ContextType
属性会被重赋值为一个由 React.createContext()
创建的 Context
对象。这能让你使用 this.context
来消费最近 Context
上的那个值。你可以在任何生命周期中访问到它,包括 render
函数中。
class Child extends Component {
render() {
return(
<CountContext.Consumer>
{ count => <h1>count: { count }</h1> }
</CountContext.Consumer>
)
}
}
// 修改为以下代码:
class Child extends Component {
const contextType = CountContext;
render() {
const count = this.context;
return(
<h1>count: { count }</h1>
)
}
}
使用useContext
import React, { Component, useState, createContext, useContext } from 'react';
function Child() {
const count = useContext(CountContext);
reutrn(
<h1>count:{count}</h1>
)
}
当组件上层最近的 <Provider>
更新时,该 Hook 会触发重渲染,并使用最新传递给Provider
的Context的value
值。
useContext
的参数必须是CContext
对象本身。
Consumer、ContextType、useContext的区别
Consumer
组件在类组件和函数组件中都可以使用
,作为消费组件,可以有多个
Provider
传值,接收多个全局变量。
ContextType
属性作为类静态成员,在函数组件中无法使用
。
ContextType
会被重赋值为一个新的Context
对象,ContextType
只能使用一个Context
,就算有多个Provider
传值,也只会接收一个值。
useContext
是函数组件中的方法
,可以有多个
Provider
传值,接收多个全局变量,useContext
解决了Consumer
组件书写繁琐的问题,还解决了ContextType
只能使用一个Context
的问题。
注
不要只是为了避免在几个层级下的组件传递 props 而使用Context
,它是被用于在多个层级的多个组件需要访问相同数据的场景。
不要滥用Context
,会破坏组件的独立性