哪些方法会触发 React 重新渲染?重新渲染 render 会做些什么 ?
参考回答
触发 React 重新渲染的主要方法有:
- 改变组件的状态(state):
当调用setState
(类组件)或useState
的更新函数(函数组件)时,React 会重新渲染组件。例如,在函数组件中使用useState
更新状态时,组件会重新渲染。 -
改变组件的属性(props):
当父组件的 props 发生变化时,子组件会重新渲染。例如,当父组件传递给子组件的值发生变化时,子组件会自动重新渲染。 -
调用
forceUpdate
(类组件):
如果直接调用类组件的forceUpdate
方法,即使状态或 props 没有变化,也会强制重新渲染组件。 -
Context 变化:
如果组件订阅了某个 React Context,当该 Context 的值发生变化时,所有使用该 Context 的组件都会重新渲染。
重新渲染(render)时做的事情:
- 重新计算虚拟 DOM:
React 会根据最新的状态和 props 重新调用组件的render
方法(对于类组件)或函数组件本身(对于函数组件),计算出一个新的虚拟 DOM(Virtual DOM)。 -
比较虚拟 DOM 和旧的虚拟 DOM:
React 使用虚拟 DOM 来优化性能。在渲染过程中,React 会将新的虚拟 DOM 与之前的虚拟 DOM 进行比较,找出不同之处。 -
更新实际的 DOM:
根据差异,React 会最小化地更新实际的浏览器 DOM,只改变那些变化了的部分,而不是重新渲染整个页面。 -
调用生命周期方法(类组件):
在类组件中,重新渲染时会依次触发一些生命周期方法,比如componentWillUpdate
、shouldComponentUpdate
、render
和componentDidUpdate
。
详细讲解与拓展
- 触发重新渲染的具体情况:
-
setState
(类组件):setState
是更新组件状态的主要方法。当setState
被调用时,React 会判断状态是否改变,如果改变,它会重新渲染该组件。“`javascript
class Counter extends React.Component {
state = { count: 0 };increment = () => {
this.setState({ count: this.state.count + 1 });
};render() {
return <button onClick={this.increment}>Count: {this.state.count}</button>;
}
}“`
每次点击按钮时,`increment` 会调用 `setState` 更新状态,触发重新渲染。 -
useState
(函数组件):函数组件通过useState
管理状态。调用useState
的更新函数(例如setCount
)时,组件会重新渲染。“`javascript
function Counter() {
const [count, setCount] = useState(0);const increment = () => {
setCount(count + 1);
};return <button onClick={increment}>Count: {count}</button>;
}“`
每次点击按钮时,`increment` 会调用 `setCount` 更新状态,触发重新渲染。 -
父组件传递的
props
变化:当父组件传递给子组件的props
发生变化时,子组件会重新渲染。即使父组件没有调用setState
,只要 props 发生变化,子组件也会更新。“`javascript
function Parent() {
const [name, setName] = useState("Alice");return <Child name={name} />;
}function Child(props) {
return <h1>Hello, {props.name}</h1>;
}“`
-
forceUpdate
:forceUpdate
是类组件中一个特殊的 API,它会强制组件重新渲染,不管状态或 props 是否变化。“`javascript
class MyComponent extends React.Component {
forceReRender = () => {
this.forceUpdate();
};render() {
return <button onClick={this.forceReRender}>Force Re-render</button>;
}
}“`
-
Context 变化:React Context 用来在组件树中共享数据。当 Context 的值发生变化时,所有订阅了该 Context 的组件都会重新渲染。
“`javascript
const MyContext = React.createContext();function Parent() {
const [value, setValue] = useState("Hello");
return (
<MyContext.Provider value={value}>
<Child />
</MyContext.Provider>
);
}function Child() {
const value = useContext(MyContext);
return <h1>{value}</h1>;
}“`
- 重新渲染的过程:
- 重新计算虚拟 DOM:React 会在状态或 props 更新时,重新计算该组件的虚拟 DOM。虚拟 DOM 是 React 用来优化性能的机制,它是实际 DOM 的一个轻量级副本。
- 比较虚拟 DOM 和旧的虚拟 DOM:React 会通过“Diffing算法”比较新旧虚拟 DOM,找出它们之间的差异,并生成更新的“补丁”。
- 更新实际的 DOM:最后,React 会通过这些“补丁”来最小化地更新真实的 DOM。这样可以避免每次更新都重绘整个页面,从而提高性能。
- 生命周期方法(仅限类组件):
- 在类组件中,每次重新渲染都会触发一些生命周期方法,通常这些方法有助于管理副作用或者控制渲染过程:
shouldComponentUpdate(nextProps, nextState)
:决定是否需要重新渲染。如果返回false
,React 会跳过渲染。render()
:重新渲染组件的 UI。componentDidUpdate(prevProps, prevState)
:在渲染完成后调用,可以在此方法中执行副作用操作。
- 在类组件中,每次重新渲染都会触发一些生命周期方法,通常这些方法有助于管理副作用或者控制渲染过程:
总结
React 重新渲染的触发条件主要包括状态(state)、属性(props)、强制更新(forceUpdate
)和 Context 变化。每次重新渲染时,React 会计算新的虚拟 DOM,与旧的虚拟 DOM 进行比较,并根据差异更新实际的 DOM。为了优化性能,React 尽量减少 DOM 的操作,使用虚拟 DOM 来高效地管理界面更新。
人机验证(防爬虫)
