I've been learning React and I read that the function returned from useEffect
is meant to do cleanup and React performs the cleanup when the component unmounts.
So I experimented with it a bit but found in the following example that the function was called every time the component re-renders as opposed to only the time it got unmounted from the DOM, i.e. it console.log("unmount");
every time the component re-renders.
Why is that?
function Something({ setShow }) {
const [array, setArray] = useState([]);
const myRef = useRef(null);
useEffect(() => {
const id = setInterval(() => {
setArray(array.concat("hello"));
}, 3000);
myRef.current = id;
return () => {
console.log("unmount");
clearInterval(myRef.current);
};
}, [array]);
const unmount = () => {
setShow(false);
};
return (
<div>
{array.map((item, index) => {
return (
<p key={index}>
{Array(index + 1)
.fill(item)
.join("")}
</p>
);
})}
<button onClick={() => unmount()}>close</button>
</div>
);
}
function App() {
const [show, setShow] = useState(true);
return show ? <Something setShow={setShow} /> : null;
}
Live example: https://codesandbox.io/s/vigilant-leavitt-z1jd2
React performs the cleanup when the component unmounts.
これをどこで読んだかわかりませんが、この説明は正しくありません。そのフックへの依存関係が変更され、新しい値でエフェクトフックを再度実行する必要がある場合、Reactはクリーンアップを実行します。この動作は、変化するデータに対するビューの反応性を維持するためのものです。公式の例として、アプリが友達のプロフィールからのステータス更新をサブスクライブするとします。あなたは素晴らしい友達なので、あなたは彼らの友達をはずし、他の誰かと友達になることにします。これで、アプリは前の友達のステータス更新の登録を解除し、新しい友達の更新を聞く必要があります。これは自然で、useEffect
動作方法を使用して簡単に実現できます。
useEffect(() => {
chatAPI.subscribe(props.friend.id);
return () => chatAPI.unsubscribe(props.friend.id);
}, [ props.friend.id ])
依存関係リストにフレンドIDを含めることで、フレンドIDが変更されたときにのみフックを実行する必要があることを示すことができます。
In your example you have specified the array
in the dependency list and you are changing the array at a set interval. Every time you change the array, the hook reruns.
You can achieve the correct functionality simply by removing the array from the dependency list and using the callback version of the setState
hook. The callback version always operates on the previous version of the state, so there is no need to refresh the hook every time the array changes.
useEffect(() => {
const id = setInterval(() => setArray(array => [ ...array, "hello" ]), 3000);
return () => {
console.log("unmount");
clearInterval(id);
};
}, []);
Some additional feedback would be to use the id directly in clearInterval
as the value is closed upon (captured) when you create the cleanup function. There is no need to save it to a ref.
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加