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
结果: