关于新提议的React Effect Hook;
Effect
钩子(useEffect()
)的优点和用例是什么?
为什么会更可取?与componentDidMount/componentDidUpdate/componentWillUnmount
(性能/可读性)有何不同?
文档指出:
在功能组件的主体内(称为React的渲染阶段),不允许进行突变,订阅,计时器,日志记录和其他副作用。
但是我认为,在生命周期方法(例如componentDidUpdate等)中使用这些行为而不是render方法已经是常识。
也有提到:
传递给useEffect的函数将在将渲染提交到屏幕后运行。
但这不是componentDidMount
和componentDidUpdate
所做的吗?
答案 0 :(得分:5)
这是 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>
);
}
答案 1 :(得分:5)
Effect
钩子(useEffect()
)的优点和用例是什么?
从根本上讲,钩子通常可以提取和重用在多个组件之间通用的状态逻辑,而无需负担高阶组件或渲染道具。
(尤其是效果钩子)的第二个好处是避免了在componentDidUpdate
中不能正确处理与状态相关的副作用的情况下可能会出现的错误(因为效果钩子确保可以设置和配置此类副作用)在每个渲染器上都拆下。)
另请参见下面详细介绍的性能和可读性优点。
任何使用生命周期方法实现状态逻辑的组件-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
答案 2 :(得分:1)
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>
);
}
```