[英]React hooks: What/Why `useEffect`?
关于新提出的React Effect Hook ;
Effect
钩子( useEffect()
)的优点和用例是什么?
为什么它更可取?它与componentDidMount/componentDidUpdate/componentWillUnmount
(性能/可读性)有何不同?
该文件指出:
函数组件的主体(称为 React 的渲染阶段)内不允许发生突变、订阅、计时器、日志记录和其他副作用。
但我认为在诸如 componentDidUpdate 等生命周期方法而不是渲染方法中拥有这些行为已经是常识。
还提到:
传递给 useEffect 的函数将在渲染提交到屏幕后运行。
但这不是componentDidMount
和componentDidUpdate
所做的吗?
Effect
钩子(useEffect()
)的优点和用例是什么?
首先,钩子通常可以提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染道具的负担。
第二个好处(特别是 Effect 钩子)是避免在componentDidUpdate
中没有正确处理依赖状态的副作用时可能出现的错误(因为 Effect 钩子确保在每次渲染时设置和拆除此类副作用) .
另请参阅下面详述的性能和可读性优势。
任何使用生命周期方法实现有状态逻辑的组件——Effect 钩子都是“更好的方法”。
为什么它更可取?它与
componentDidMount
/componentDidUpdate
/componentWillUnmount
(性能/可读性)有何不同?
因为上面和下面详述的优点。
效果挂钩——
效果挂钩导致:
更简单和更易于维护的组件,因为能够将以前必须在同一组生命周期方法中表达的不相关行为拆分为每个此类行为的单个钩子 - 例如:
componentDidMount() { prepareBehaviourOne(); prepareBehaviourTwo(); } componentDidUnmount() { releaseBehaviourOne(); releaseBehaviourTwo(); }
变成:
useEffect(() => { prepareBehaviourOne(); return releaseBehaviourOne; }); useEffect(() => { prepareBehaviourTwo(); return releaseBehaviourTwo; });
注意,有关代码BehaviourOne
现在清楚地从与分离BehaviourTwo
,而在此之前这是每个生命周期方法中的混杂。
更少的样板,因为不需要在多个生命周期方法中重复相同的代码(例如componentDidMount
和componentDidUpdate
之间很常见)——例如:
componentDidMount() { doStuff(); } componentDidUpdate() { doStuff(); }
变成:
useEffect(doStuff); // you'll probably use an arrow function in reality
这是ReactConf2018 Dan Abramov 的演讲中解释差异的一个例子:
以下是以下示例的一些发现:
useEffect()
访问生命周期更新和状态更新与 componentDidMount 和 componentDidUpdate 不同,传递给 useEffect 的函数在布局和绘制后触发,在延迟事件期间
useEffect()
钩子来更有效地控制组件重新渲染,这在您仅在安装和卸载时仅传递空数组 [] 来渲染组件时非常有效。useEffect()
钩子来分离关注点并做出反应:Hooks 允许我们根据代码正在做什么而不是生命周期方法名称来拆分代码。 React 将按照指定的顺序应用组件使用的每个效果
使用类:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
使用钩子:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect 在状态改变时运行。
import { useState, useEffect } from 'react';
function Example() {
const [Age, setAge] = useState(33);
const [Somestate,setSomestate]=useState(initilaestate);
useEffect(() => {
console.log('the age is changed to ',Age);
});
// you can use useEffect as many times you want in you component
useEffect(() => {
console.log('the age is changed to ',Age);
},[someState]);//here you tell useEffect what state to watch if you want to watch the changing of a particular state and here we care about someState
return (
<div>
<p>age increased to {Age}</p>
<button onClick={() => setAge(count + 1)}>
Increase age by One
</button>
</div>
);
}
```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.