反応v16.7.0で導入されたフックを使用しました。
https://reactjs.org/docs/hooks-intro.html
したがって、フックについての私の理解は、reactでクラスコンポーネントを記述することなく、機能コンポーネントの状態を操作できることです。これは本当に素晴らしい機能です。
しかし、機能コンポーネントでフックを使用することについて、明確なイメージが得られていません。
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
フックを使用する場合、上記の機能コンポーネントでライフサイクルメソッドを使用するにはどうすればよいですか?
最も一般的なライフサイクルの例を次に示します。
componentDidMount
空の配列を2番目の引数としてuseEffect()
に渡し、マウント時にのみコールバックのみを実行します。
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []); // Pass an empty array to run only callback on mount only.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
componentDidUpdate
(緩い)単一の引数をuseEffect
に渡すだけで、レンダリングのたびに実行されます。 componentDidUpdate
は最初のレンダリング後に実行されないが、このフックバージョンはすべてのレンダリング後に実行されるというわずかな違いがあるため、これは緩やかな同等です。
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}); // No second argument, so run after every render.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
componentDidUpdate
(厳密)この例と上記の例の違いは、ここのコールバックは最初のレンダリングでは実行されず、componentDidUpdate
のセマンティクスを厳密にエミュレートすることです。これ 答えはTholleによる 、すべてのクレジットは彼に送られます。
function Example() {
const [count, setCount] = useState(0);
const firstUpdate = useRef(true);
useLayoutEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
console.log('componentDidUpdate');
});
return (
<div>
<p>componentDidUpdate: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
componentWillUnmount
useEffect
のコールバック引数でコールバックを返すと、アンマウントする前に呼び出されます。
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Return a callback in useEffect and it will be called before unmounting.
return () => {
console.log('componentWillUnmount!');
};
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
shouldComponentUpdate
React.PureComponent
またはReact.memo
を使用して、コンポーネントレベルで既にこれを実現できます。子コンポーネントの再レンダリングを防ぐために、この例は React docs から取得されます。
function Parent({ a, b }) {
// Only re-rendered if `a` changes:
const child1 = useMemo(() => <Child1 a={a} />, [a]);
// Only re-rendered if `b` changes:
const child2 = useMemo(() => <Child2 b={b} />, [b]);
return (
<>
{child1}
{child2}
</>
)
}
getDerivedStateFromProps
繰り返しますが、 React docs
function ScrollView({row}) {
let [isScrollingDown, setIsScrollingDown] = useState(false);
let [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row changed since last render. Update isScrollingDown.
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(row);
}
return `Scrolling down: ${isScrollingDown}`;
}
getSnapshotBeforeUpdate
フックに相当するものはまだありません。
componentDidCatch
フックに相当するものはまだありません。
Reactチームはこの目的のためにuseEffect
フックを提供しました。例のコンポーネントを取り、カウントのためにサーバーのアップロードを追加しましょう。そうでなければ、たとえばcomponentDidUpdate
に入れます:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
fetch(
'server/url',
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({count}),
}
);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
それはそうではないので、これはこの例では大きな勝利のようには見えません。しかし、ライフサイクルメソッドの問題は、コンポーネントでそれぞれ1つしか取得できないことです。サーバーにアップロードし、イベントをトリガーし、メッセージをキューに入れて、それらがどれも関連していない場合はどうでしょうか?残念なことに、それらはすべてcomponentDidUpdate
に詰め込まれています。または、やりたいn
事柄のために、n
ラップされたHOCのレイヤーがあります。ただし、フックを使用すると、不要なHOCレイヤーなしで、これらすべてをuseEffect
への分離された呼び出しに分割できます。
まあ、あなたは本当にライフサイクルメソッドを持っていません。 =)しかし、ここに示すようにエフェクトフックを使用できます https://reactjs.org/docs/hooks-effect.html
エフェクトフックは、componentDidMount、componentDidUpdate、およびcomponentWillUnmountの動作を複製できます。
したがって、コンポーネントにライフサイクルメソッドは本当に必要ありません。代わりに、エフェクトフックが代わりに使用されます。 =)
上記のリンクを読むと、それらがどのように機能するかについていくつかの例が得られます。