原文链接:https://www.jianshu.com/p/cc91178724d5
一、什么是useContext
在Hooks出来之前,开发者都是使用的class组件,通过props传值。现在使用方法组件(Function)开发了,没有constructor构造函数也就没有了props的接收,所以父子组件的传值就成了一个问题。
React Hooks
就为我们准备了useContext来解决这个问题。
二、useContext的作用
1.useContext可以帮助我们跨越组件层级直接传递变量,实现数据共享。
- 这里要注意的是,很多同学觉得可以使用useContext结合useReducer来替代redux,其实两者的作用是不同的。
- useContext:解决组件间传值的问题。
- redux:统一管理应用状态。
- 所以,我们可以使用useContext结合useReducer来模拟一个小型redux场景,而无法替代redux
2.Context的作用就是对它所包含的组件树提供全局共享数据的一种技术。
三、代码示例
1、新建example.tsx
import React, { useState, createContext, useContext } from "react";
const Example = () => {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>父组件点击数量:{count}</p>
<button onClick={() => setCount(count + 1)}>{"点击+1"}</button>
</div>
);
};
export default Example;
2、在example.tsx创建Context
const CountContext = createContext(0);
3、在example.tsx创建子组件Counter,通过useContext把刚刚创建好的CountContext作为参数传进去,并读取count值
const Counter = () => {
const count = useContext(CountContext);
return <p>子组件获得的点击数量:{count}</p>;
};
4、使用CountContext.Provider包裹需要接收参数的子组件,并通过value传值
<CountContext.Provider value={count}>
<Counter />
</CountContext.Provider>
5、最终示例代码:
import React, { useState, createContext, useContext } from "react";
const CountContext = createContext(0);
const Example = () => {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>父组件点击数量:{count}</p>
<button onClick={() => setCount(count + 1)}>{"点击+1"}</button>
<CountContext.Provider value={count}>
<Counter />
</CountContext.Provider>
</div>
);
};
const Counter = () => {
const count = useContext(CountContext);
return <p>子组件获得的点击数量:{count}</p>;
};
export default Example;
总结:
- 使用 const A = React.createContext<Type>(...初值) 创建初值
- <A.Provider value={父组件中对应的值}> <子组件> </A.Provider>
- 子组件中使用 const val = React.useContext(A) 获取到对应的值
四、高级用法
1、新建 addContext.ts 文件
import React from 'react';
interface AddContextType {
code?: string;
selection: boolean[];
onSelectionChange: (status: boolean, index: number) => void;
time?: string[];
setRuleTime: (val: string) => void;
}
export const AddContext = React.createContext<AddContextType>({
code: undefined,
selection: [false, false],
onSelectionChange: () => undefined,
time: undefined,
setTime: () => undefined,
});
2、父组件 index.tsx
import React, { useMemo, useState } from 'react';
import type { ManageState, ConnectProps, Loading } from 'umi';
import { AddContext } from './AddContext';
type IProps = {
manage: ManageState;
loading: boolean;
} & ConnectProps;
const Manage: React.FC<IProps> = {
// useMemo 一言以蔽之,做性能优化用的,如果说类组件的性能优化的方法是
// shouldComponentUpdate 和 PureComponent,
// 那么给函数组件做性能优化的就是这个 useMemo
const formContext = useMemo(() => {
return {
...formData,
code,
time,
setTime
}
},[
formData,
time
])
<AddContext.Provider value={formContext}>
}
export default connect(
({ manage, loading }: { manage: ManageState; loading: Loading }) => ({
Manage,
loading: loading.models.manage,
}),
)(Manage);