上一篇介绍过 State Hook 用来储存状态,Effect Hook 则用来处理 function component 中的副作用,像是资料 fetch、或手动改变 DOM 等等。使用 Class 跟 Effect Hook 差别能感受到不同切割 React 更新的逻辑,从固定的时间到更大弹性的 render 前後变化。 Effect Hook 对照 Class 生命周期也可以看作是 componentDidMount,componentDidUpdate 和 componentWillUnmount 的组合,够大的意义是将这些分散的不同地方的逻辑,但其实是 建构与清除(ex: addEventListener, removeEventListener, setTimeout, clearTimeout) 成对的逻辑,重新集中关注点。
function TestUseState() {
const [title, setTitle] = React.useState("I am waiting...");
const [count, setCount] = React.useState(0);
React.useEffect(() => {
async function getTitle() {
let response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
response = await response.json()
setTitle(response.title)
}
getTitle()
});
React.useEffect(() => {
// 使用浏览器 API 更新文件标题
document.title = `You clicked ${count} times`;
});
return (
<div>
<h1>Hello UseEffect Hook</h1>
<h3>Title Async : { title }</h3>
<h3>Title Count : { count } times</h3>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
当 side effect 使用到 setTimeout 、监听事件或其他外部资源时,就需要注意去清除 timer、listener 或外部资源 socket 等。而清除使用 return function 的方式,
useEffect(() => {
const timer = setTimeout(() => {
console.log('This will run after 1 second!')
}, 1000);
return () => clearTimeout(timer);
}, []);
告诉 React 你的 component 需要在 render 後做一些事情。通常 componentDidMount 和 componentWillUnmount 成对的,但生命周期中只会执行一次,而中间如有变化可能会造成错误。也就是为什麽 在 component 内部呼叫 useEffect,比起用时间周期来切分, render 前後切分降低在撰写 建造与清除 的程序可以更集中。
=> 只执行一次 unmounting 可能发生的错误,当中间又触发 prop ,unsubscribe 的部分可能 cancel 掉错误的 id 造成 memory leak。
Class Component 的 Bug 例子:
componentDidMount() {
ChatAPI.subscribeToFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
componentWillUnmount() {
ChatAPI.unsubscribeFromFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
=> 使用第二个参数,可以够有效率的监控资料变化
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
以上今天。
参考资料:
https://zh-hant.reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
https://stackoverflow.com/questions/61885496/how-to-cancel-socket-io-client-subscription-in-react
>>: [Day 16] MySQL下载注意事项(Mac版)
今天开始要介绍 Structural patterns。先前的 Creational pattern...
今天我们正式要使用 Markdown 撰写你的第一篇部落格文章啦! 用指令建立文章或草稿 .md 档...
做出左右滑动的互动行为 今天要来操作这个 Container ,其实就可以把它想成「一组」东西就好了...
从 IT 技术面细说 Search Console 的 27 组数字 KPI (22) :KPI 总...
制作表单 createRadio(); 沿用上一个文章的参考 加上以下设定 我们可以用radio去做...