フックとは
フックは構文的には関数です。これらの関数を使用して、状態管理およびライフサイクル メソッドを機能コンポーネントに導入できます。
React フックの利点
- 簡潔
文法的に言えば、記述されるコードが少なくなります - 始めるのはとても簡単です
- 関数型プログラミングの概念に基づいており、JavaScript の基本知識を習得するだけで済みます。
- React Hooks はライフサイクルに関する知識を学ぶ必要がなく、新しい概念を使用してコンポーネントの動作プロセスを管理します。
- HOC関連の知識を学ぶ必要はなく、HOCが解決したい問題をReact Hooksで完璧に解決でき、より確実です。
- Mobx は状態管理において Redux を置き換えます
- コードの再利用性の向上
- Typescript との統合が容易になりました
React フックの欠点
- 状態が同期していません
非同期操作関数でアクセスされた状態は、元の状態の値のままです - useEffect の依存関係の問題
useEffect がより多くのデータに依存すると、頻繁にトリガーされます
React Hooks に関する注意事項
- 命名規則
カスタム フックは、useXXX の形式で、プレフィックスとして use を使用して名前を付ける必要があります。 - 最外層の React Hook のみを呼び出す
- 反応関数からのみ反応フックを呼び出します
カスタム フックまたはコンポーネントでフックを呼び出します
リファレンスフック
コンポーネント内の要素またはその他のデータは、機能コンポーネントに保存/取得できます。
useRef
useRef(initialValue) は、現在のプロパティを 1 つだけ持つ可変 ref オブジェクトを返します。初期値は渡されたパラメーターのInitialValue であり、返された ref オブジェクトはコンポーネントのライフ サイクルを通じて変更されません。
効果:
- React.createRef() と同様に、DOM ノードのインスタンスを取得するために使用されます。
- レンダリング サイクル間で共有データを保存します
- DOM ノードのインスタンスを取得する
import {useRef} from 'react'
function APP(){
const userRef = useRef(null);
const clickButton = ()=>{
if(userRef.current){
console.log(userRef.current);
}
}
return <div>
<input name="username" ref={userRef} />
<button onClick={clickButton}>show</button>
</div>
}
- 共有データを保存する
import {useRef,useState} from 'react' function APP(){ const [count,setCount] = useState(0); const countRef = useRef(null); const preCount = countRef.current; useEffect(()=>{ countRef.current = count; }); const clickButton = ()=>{ setCount(count+1); } return <div> <input name="username" /> <button onClick={clickButton}>show</button> </div> }
予防
- コンポーネントがレンダリングされるたびに、useRef の戻り値は変更されません。
- ref.current を変更しても再レンダリングは発生しません
- レンダリングでは ref.current の値を更新できません。そうしないと、ref.current の値が正しく計算されなくなります。
これは、他のデータが変更されると、レンダリングがリセットされると、ref.current が更新され、計算エラーが発生します。 - 要素属性の ref の値は、useRef によって返されるオブジェクト以外の値にすることはできません。
- ref.current の値を変更しても useEffect はトリガーされません
前方参照
機能コンポーネントに ref を適用すると、コンポーネントのインスタンスが取得されません。したがって、forwardRef を使用する必要があります。
forwardRef は、受け取った ref 属性を独自のコンポーネント ツリーに転送できる React コンポーネントを作成します。
forwardRef() の使用法は、コンポーネントをラップすることです。
import {forwardRef,useRef,useEffect} from 'react'
const Child = forwardRef((props,ref)=>{
return <input ref={ref} type="text" />
});
function App(){
const childRef = useRef(null);
useEffect(()=>{
childRef.current.focus();
});
return <>
<Child ref={childRef}></Child>
</>
}
useImperativeHandle
useImperativeHandle を使用すると、useRef がコンポーネントのすべてのプロパティとメソッドを取得するという問題を解決するために、コンポーネントが公開する必要がある ref データをカスタマイズできるようになります。
useImperativeHandle(ref,handle,[deps]):
- ref: 公開する必要がある ref 参照
- handle: は関数です。戻り値は ref.current の値として使用されます。
- deps: 依存データ、監視が必要なステータス
import {useRef,useImperativeHandle,forwardRef} from 'react'
const Child = forwardRef((props,ref){
useImperativeHandle(ref,()=>{
return {
focus:()=>ref.current.focus()
}
},[props.value]);
retunr <input ref={ref} value={props.value} />
});
function App(){
const childRef = useRef(null);
return <>
<Child ref={childRef}></Child>
</>
}
予防
- useImperativeHandle と React.forwardRef は一緒に使用する必要があります。一緒に使用しないと、実行時にエラーが直接報告されます。
- useImperativeHandle を使用した後、親コンポーネントと子コンポーネントにそれぞれ独自の ref を持たせることができ、React.forwardRef を通じて親コンポーネントの ref を渡し、useImperativeHandle メソッドを通じて親コンポーネントへの現在のオープンをカスタマイズします。