使用 React.memo 和 useCallback 来防止函数导致重新渲染
Using React.memo and useCallback to prevent functions from causing re-renders
我正在关注 this tutorial 演示 React 的 'useCallback' 钩子以及 React.memo 以防止函数被不必要地渲染。为了证明我们使用 useRef 来控制渲染数量的概念。这仅适用于该功能,但我添加了一个功能来随机化按钮背景颜色,我似乎无法阻止这两个功能的呈现。
import React,{useState, useCallback, useRef} from 'react';
import './App.css';
const randomColor = () => `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`
const Button = React.memo(({increment, bgColor}) => {
const count = useRef(0)
console.log(count.current++)
return(
<button onClick={increment} style={{backgroundColor: bgColor}}>increment</button>
)
})
const App = React.memo(() => {
const [count, setCount] = useState(0)
const [color, setColor] = useState(`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`)
const increment = useCallback(() => {
setCount(previousCount => previousCount + 1)
setColor(randomColor)
},[setCount,setColor])
return (
<div className="App">
<header className="App-header">
<h2>{count}</h2>
<Button increment={increment} bgColor={color}>increment</Button>
</header>
</div>
);
})
export default App;
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
import React,{useState, useCallback, useRef} from 'react';
import './App.css';
const randomColor = () => `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`
const Button = React.memo(({increment, bgColor}) => {
const count = useRef(0)
console.log(count.current++)
return(
<button onClick={increment} style={{backgroundColor: bgColor}}>increment</button>
)
})
const App = React.memo(() => {
const [count, setCount] = useState(0)
const [color, setColor] = useState(`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`)
const increment = useCallback(() => {
setCount(previousCount => previousCount + 1)
setColor(randomColor)
},[setCount,setColor])
return (
<div className="App">
<header className="App-header">
<h2>{count}</h2>
<Button increment={increment} bgColor={color}>increment</Button>
</header>
</div>
);
})
export default App;
就是你说的视频中的例子,Button组件是不会变的,因为props是一直不变的。在您的示例中,increment
保持不变,但问题是 bgColor
会随着每次点击而变化。
也就是说,如果只渲染主组件而不渲染Button组件,背景必须是一样的,但是因为每次接收的背景颜色都不同,所以没有意义。
如果 props 发生变化(如果你没有实现自定义的 shouldUpdate 生命周期方法),React 总是会重新渲染组件。
我正在关注 this tutorial 演示 React 的 'useCallback' 钩子以及 React.memo 以防止函数被不必要地渲染。为了证明我们使用 useRef 来控制渲染数量的概念。这仅适用于该功能,但我添加了一个功能来随机化按钮背景颜色,我似乎无法阻止这两个功能的呈现。
import React,{useState, useCallback, useRef} from 'react';
import './App.css';
const randomColor = () => `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`
const Button = React.memo(({increment, bgColor}) => {
const count = useRef(0)
console.log(count.current++)
return(
<button onClick={increment} style={{backgroundColor: bgColor}}>increment</button>
)
})
const App = React.memo(() => {
const [count, setCount] = useState(0)
const [color, setColor] = useState(`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`)
const increment = useCallback(() => {
setCount(previousCount => previousCount + 1)
setColor(randomColor)
},[setCount,setColor])
return (
<div className="App">
<header className="App-header">
<h2>{count}</h2>
<Button increment={increment} bgColor={color}>increment</Button>
</header>
</div>
);
})
export default App;
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
import React,{useState, useCallback, useRef} from 'react';
import './App.css';
const randomColor = () => `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`
const Button = React.memo(({increment, bgColor}) => {
const count = useRef(0)
console.log(count.current++)
return(
<button onClick={increment} style={{backgroundColor: bgColor}}>increment</button>
)
})
const App = React.memo(() => {
const [count, setCount] = useState(0)
const [color, setColor] = useState(`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255}`)
const increment = useCallback(() => {
setCount(previousCount => previousCount + 1)
setColor(randomColor)
},[setCount,setColor])
return (
<div className="App">
<header className="App-header">
<h2>{count}</h2>
<Button increment={increment} bgColor={color}>increment</Button>
</header>
</div>
);
})
export default App;
就是你说的视频中的例子,Button组件是不会变的,因为props是一直不变的。在您的示例中,increment
保持不变,但问题是 bgColor
会随着每次点击而变化。
也就是说,如果只渲染主组件而不渲染Button组件,背景必须是一样的,但是因为每次接收的背景颜色都不同,所以没有意义。
如果 props 发生变化(如果你没有实现自定义的 shouldUpdate 生命周期方法),React 总是会重新渲染组件。