🦯 Hook
🦯 Hookとは?
関数型構成部品では、クラスのライフサイクルメソッド機能とステータス管理機能があります.
🤔 Hookを作ったきっかけは?
既存の使いたいstateを複数のコンポーネントに書く場合はpropsで渡します.
ただし、各構成部品のstateを渡すには、各親構成部品にpropsを渡す必要があります.
これらの問題を解決するために,高次コンポーネントまたはレンダリングpropsを提案した.
class componentでの問題
1. ステータスロジックの再利用が困難
上述したように、複数のコンポーネント間でstateを共有するために、提示propsまたはHOCS論理モードが使用される.
ステータス共有を効率的に行うことができるという利点があるが、メンテナンスと可読性の面では、コードの複雑さを招き、WrapperHellを招き、コード追跡が困難になるという欠点がある.
Hookを使用すると,素子から状態に関する論理を抽象化することができる.
Hookは、階層を変更せずにステータス関連ロジックを再使用するのに役立ちます.これにより、多くのコンポーネントやコミュニティ間でHookを共有することが容易になります.
2.構成部品の複雑さ
クラス構成部品では、同様のライフサイクルメソッドで同じ操作が繰り返される場合があります.
(例えば、ComponentDidmount、ComponentDidUpdateからデータをロードする)
これは同じ仕事を繰り返すトラブルが発生し、不便をもたらします.
これらの欠点を補うために、Hookは、同様の機能を有するライフサイクル法を1つのHook APIで解決することを可能にする.(ex. useEffect)
3.等級が難しい
propsをsuperに渡してstateを宣言し、構造関数メソッドでstateを宣言します(外部で簡単に解決することもできます).ある機能を実現するための方法を定義して使用する場合は、thisを使用してバインドする必要があります.(クラスフィールドとしても使用できます.)
Hookはこれらの複雑なthisを用いず,関数素子で実現することによって問題を解決する.
フックの種類
useState
useStateはHook APIであり、関数コンポーネントでstateを使用および管理できます.
useStateは、ステータス値とステータス値を変更する関数を含む配列を返します.
名前は構造分解によって命名されます.
userStateのパラメータはstateの初期値を指定します.
import React, { useState } from "react";
const App = () => {
const [count,setCount] = useState(0) // 원하는 이름 명명 및 초깃값 설정
console.log(useState(0)); // state와 state를 변경해주는 함수 반환
return <div></div>;
};
export default App;
useState(0)の戻り値一般に、一般変数は関数終了時に消失するが、状態変数はreactによって消失しない.
複数のステータス使用を設定する場合は、複数のユーザーステータスを宣言できます.
functional update
const [state,setState] = useState(initValue)
setState()が前の状態値に依存して次の状態値を設定する場合、setState()に関数を割り当てることができます.setState( prevstate => prevstate + 1)
以前のstate値を参照してstate値を設定する必要がある場合に便利です.また、関数式更新がsetStateに変更されていない場合は、再表示されません.
useEffect
useEffectはHookAPIであり、関数型素子においてクラス素子ライフサイクル法と同様の機能を実現することができる.
ライフサイクルメソッドコンポーネントDidMountまたはコンポーネントDidUpdate、コンポーネントWillUnmountなどの目的で提供されますが、APIに統合されています.
データインポート、サブスクリプション設定、DOM操作などの効果をuserEffectで設定します.
(DOM変更利用可能タイマー設定またはuseLayoutEffect)
最初のパラメータとしての関数の役割はeffectである.
effectを設定する方法は、関数の文で初期レンダリングと更新レンダリングを設定した後に必要な操作です.
設定したタスク(effect)を解除する方法は、関数で解除した関数を返すことです.(componentWillUnmount)
userEffectのclean-up関数(returnで設定した関数)は、アンインストール時に呼び出されません.
clean-up関数は、構成部品を更新する前に呼び出されます.
2番目のパラメータはdependencyです.
2番目の因子は配列を入れることですが、配列内では値が変更された場合にのみ効果が発生します.
空白の配列を追加すると、最初のレンダリング時にのみ効果が得られます.
相互に関連する論理は、userEffectを複数回使用して区別することができる.
(クラス構成部品では、ライフサイクルメソッドで関連のない論理を強制的に実行する必要があります.)
(stateを変更するたびに再レンダリングされ、レンダリングするたびにuserEffectが実行され無限ループに陥ります.)
useReducer
useReducerは、useStateよりも豊富な素子の場合に、他の値がない場合にデート時に使用するhookです.
リダイレクトは、現在のステータスと更新に必要な情報を含むアクション値を受信し、新しいステータスを返す関数です.
reducer関数で新しいステータスを作成する場合は、不変性を維持する必要があります.
useReducerの最初のハエパラメータにはReducer関数が含まれ、2番目のパラメータにはReducerのデフォルト値が含まれます.
const [state,dispatch] = useReducer(reducer,0)
このhookを使用してstate値とdispatch関数を受信します.ここでstateは現在指す状態であり、dispatchは動作を生成する関数である.dispatch(action)
state、actionをオブジェクトとして使用する場合import React, { useReducer } from "react";
const App = () => {
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return { value: state.value + 1 };
case "DECREMENT":
return { value: state.value - 1 };
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, { value: 0 });
return (
<div>
<p>현재 카운터 값은 {state.value}입니다.</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>INCREMENT</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>DECREMENT</button>
</div>
);
};
export default App;
state、action値を非オブジェクト値として使用する場合
import React, { useReducer } from "react";
const Base = () => {
function reducer(state, action) {
switch (action) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, 0);
return (
<div>
<h1>value</h1>
<button onClick={() => dispatch("INCREMENT")}>INCREMENT</button>
<button onClick={() => dispatch("DECREMENT")}>DECREMENT</button>
</div>
);
};
export default Base;
reducerで使用されるアクションオブジェクトには、アクションのタイプを示すtypeフィールドが必要ですが、ユーザーreducerで使用されるアクションオブジェクトには必ずしもtypeがあるとは限りません.また、userreducerでは、動作値はオブジェクトでなくてもよいし、文字列や数字であってもよい.
ドアではなくスイッチドアなら?
なぜよく使われるif文ではなくswitch文を使うのでしょうか.
if (action === "INCREMENT") state + 1;
else if (action === "DECREMENT") state - 1;
else state;
上述したようにifゲートを用いる場合は毒性が悪いようで、減速機の趣旨上、switchゲートを用いることが適切であると考えられる.switch文は、条件に合致するcaseを使用するために様々なcaseを設定することができ、これはusereducerの趣旨の複数の動作の中で使用を選択することを意味するので、より適切である.
import React, { useReducer } from "react";
const App = () => {
function reducer(state, action) {
return {
...state, //기존 state값 가져오기
[action.name]: action.value,
};
}
const [state, dispatch] = useReducer(reducer, { name: "", nickname: "" });
const onChange = (e) => {
dispatch(e.target);
};
console.log("render");
return (
<div>
<div>
<input name="name" value={state.name} onChange={onChange} />
</div>
<div>
<input name="nickname" value={state.nickname} onChange={onChange} />
</div>
<h1>이름 : {state.name}</h1>
<h1>별칭 : {state.nickname} </h1>
</div>
);
};
export default App;
reduce関数にswitch文を書く必要はありません.action値に異なる値を割り当てることもできます.When use?
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.
https://reactjs.org/docs/hooks-reference.html#usereducer
useReducerは、複雑なstateロジックまたは次のstateが前のstateに依存するために使用されます.
(actionに従って複数のstateを操作できるため)
Reference
この問題について(🦯 Hook), 我々は、より多くの情報をここで見つけました https://velog.io/@kcj_dev96/Hookテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol