useContext()可以用于组件之间共享状态。
使用方法
1.引入createContext, useContext
2.通过createContext来创建句柄
3.通过Context.Provider来确定共享范围
4.通过value来分发内容
5.在子组件中通过useContext(Context)来获取数据
现在有俩组件,需要共享状态,如下:
<div className="test">
<Navbar />
<Messages />
</div>
第一步:在它们的父组件上使用React的Context API,在组件外部创建有一个Context
const TestContext = React.createContext({
});
第二步:TestContext.Provider提供了一个Context对象,这个对象是可以被子组件共享的
<TestContext.Provider
value={
{
username: 'superawesome',
}}
>
<div className="test">
<Navbar />
<Messages />
</div>
<TestContext.Provider/>
第三步:使用useContext()钩子函数来引入Context对象,从中获取username属性
const Messages = () => {
const {
username } = useContext(TestContext);
return (
<div className="messages">
<p>1 message for {
username}</p>
</div>
)
}
所有代码如下:
import React, {
useContext, createContext } from "react";
import ReactDOM from "react-dom";
const TestContext= createContext({
});
const Navbar = () => {
const {
username } = useContext(TestContext)
return (
<div className="navbar">
<p>{
username}</p>
</div>
)
}
const Messages = () => {
const {
username } = useContext(TestContext)
return (
<div className="messages">
<p>1 message for {
username}</p>
</div>
)
}
function App() {
return (
<TestContext.Provider
value={
{
username: 'superawesome',
}}
>
<div className="test">
<Navbar />
<Messages />
</div>
<TestContext.Provider/>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
注意点:
使用了useContext的组件总会在context值变化时重新渲染,相当于useContext可以读取context的值以及订阅context的变化。即使祖先使用React.memo或者shouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染。
看个例子:
import React, {
useState, createContext } from "react";
import Test6 from "./Test6";
export const testContext = createContext({
})
const App = () => {
const [count, setCount] = useState(0)
const addCount = () => {
setCount(count+1)
}
return (
<>
<testContext.Provider value={
{
count}
}>
<Test6 />
</testContext.Provider>
<button onClick={
addCount}>{
count}</button>
</>
);
}
export default App;
Test6.js
import React, {
useContext } from 'react'
import {
testContext } from './App'
const Test6 = React.memo(() => {
let {
count} = useContext(testContext)
return (
<div>
{
count}
</div>
)
})
export default Test6
结果:
每更改count的值,Test6组件即使用了memo也会重新渲染。