import React, { useState, memo } from "react";
let Theme = React.createContext({color:"red"});
const Inner = memo(() => {
let theme = React.useContext(Theme);
console.log("Inner")
return <div><span style={{color: theme.color}}>文字</span></div>
})
const Con = () => {
return <Inner />
}
const Side = memo(() => {
console.log("side")
return <><span>side</span></>
})
export default function App() {
const [color, setColor] = useState("red")
const [count, setCount] = useState(0);
return (
<div className="App">
<div>
{count}
<button onClick={() => setCount((v) => v + 1 )}>count</button>
</div>
<button onClick={() => setColor("red")}>红色</button>
<button onClick={() => setColor("green")}>绿色</button>
<Theme.Provider value={{color}}>
<Con />
<Side />
</Theme.Provider>
</div>
);
}
上述的代码中,因为父组件 App 重新渲染时提供给Conext 的都是一个新的字面量对象,导致Inner 组件会在父组件的每次重渲染中去跟着重新渲染,这实际上是没有必要的。
import React, { useState, memo } from "react";
let Theme = React.createContext({color:"red"});
const Inner = memo(() => {
let theme = React.useContext(Theme);
console.log("Inner")
return <div><span style={{color: theme.color}}>文字</span></div>
})
const Con = () => {
return <Inner />
}
const Side = memo(() => {
return <><span>side</span></>
})
export default function App() {
const [theme, setTheme] = useState({color: "red"})
const [count, setCount] = useState(0);
return (
<div className="App">
<div>
{count}
<button onClick={() => setCount((v) => v + 1 )}>count</button>
</div>
<button onClick={() => setTheme({color: "red"})}>红色</button>
<button onClick={() => setTheme({color: "green"})}>绿色</button>
<Theme.Provider value={theme}>
<Con />
<Side />
</Theme.Provider>
</div>
);
}