[反応技術]第8章Hooks
hooksって何ですか?^^
また、ユーザ状態管理機能や、レンダリング後のタスクのユーザ効果->既存の関数構成部品ではできない機能も用意されています.より多くの作業を支援今日の実習は?ストリーム:
応答内蔵Hooks->カスタムHooksの作成
yarn create react-app hooks-tutorial
ダメな場合↓
npm create react-app hooks-tutorial
useStateは最も基本的なHookであり、関数素子を可変状態に保つことができる .の機能要素でステータスを管理する必要がある場合-> を使用
useState機能によるデジタルカウンタの実装
この関数にパラメータを追加し、呼び出し時に渡されるパラメータに値を置き換えます->構成部品が正常にレンダリングされます
App.jsをレンダリングします^^
(クラスに変換する必要はありません)
1つのuseState関数で管理できるのは->1つのステータス値のみです
複数のステータスを管理する必要がある場合は?->複数使用useState
srcディレクトリのInfo.jsファイルの作成
App.jsレンダリング 出力画面
userEffectって何ですか?^^
反応素子をレンダリングするたびに特定の操作を実行するように設定できるHook.
クラス構成部品の構成部品DidMount+構成部品DidUpdate=UserEffect既存のInfoコンポーネントUSEffect を適用は最初のスクリーンレンダリング時のみ実行され、更新時には実行されませんか?->関数の2番目のパラメータを使用して、空の配列 を配置します.
useEffectを使用する場合、一部の値が変更された場合にのみ呼び出されますか?
クラスエレメントなら?
がuseEffectでこの操作を適用した場合?
userEffectに渡される2番目のパラメータの配列に、チェックしたい値を入れます.
デフォルトでは、userEffectはレンダリング直後に実行されます.
実行条件は、2番目のパラメータ配列に何を配置するかによって異なります.
構成部品をアンインストールまたは更新する前に、どのような操作を行いますか?userEffectはクリーンアップ関数(cleanup)を返します.
useEffectセクションを変更するには、次の手順に従います.
AppコンポーネントにInfoコンポーネントの可視性を変更
レンダリングするたびに、ポストアレンジ関数が表示されます.
呼び出し後の整理関数の表示時に更新される前の値
アンインストール時にクリーンアップ関数だけを呼び出したい場合は?
userEffect関数の2番目のパラメータに空の配列を追加
userreducerとは?
Hook(17章減速機の概念を参照)は、素子によって異なる状態を異なる値に更新するために使用される.
Reducerとは?
現在のステータスと更新に必要な情報を含むアクション値を渡し、関数->不変性を維持動作値は、 の形式で構成する. UseReducerで使用されるアクションオブジェクトには、タイプがある必要はありません.また、非オブジェクト文字列や数値がある必要はありません.
の最大の利点は? は、構成部品更新ロジックを構成部品から除外できることを示す App.jsで をレンダリングする
usereducer->Infoコンポーネントの入力ステータスの管理
usereducerを使用する場合->入力ラベルにname値->e.targetを指定します.タスクは、name->Stateの設定と同様に処理されます.
Info.jsは以下のように変更されます.
なぜusemoを使うのですか?関数型素子内部の演算を最適化します. Average.jsファイル の作成 App.jsで をレンダリングする
usemo hook->最適化タスクの使用
レンダー中に値の一部が変化した場合にのみ実行->演算
Average.jsファイルの変更
useCallbackとは?
userMemoによく似た関数
レンダリングのパフォーマンスを最適化する必要がある場合に使用
イベントハンドラ関数が必要な場合にのみ作成できます useCallbackを使用してAverageを行います.jsコンポーネント最適化(onChange、onInsert関数、レンダリングのたびに作成される関数->最適化) UseCallbackはHook で、関数を返すときにより便利に使用できます.数字、文字列、オブジェクト->userMemo などの共通値を繰り返し使用するには関数を再利用するには、->useCallback
userefとは? Hookは を提供し、refが関数素子で容易に使用できるようにする. Average構成部品の登録ボタンを変更し、入力位置にフォーカスを合わせます. userefを使用してrefを設定すると、userefによって作成されたオブジェクトの現在の値は、実際の領域 を指します.
他の構成部品のローカル変数を使用する場合、ユーザーはRefを使用できます.
ローカル変数とは?
レンダリングを考慮せずに変更可能な値を示します.
クラス形式で作成された構成部品の場合->ローカル変数を使用する必要がある場合
これらのコードを関数要素として使用する場合は? refの値が変更されても、要素 はレンダリングされません.レンダリングに関係のない値を管理する場合にのみ、 が作成されます.
以前にInfoコンポーネントによって作成された複数の入力を管理するためのReducerを使用する論理を->Inputsを使用するHookに分離する
useInputs.jsファイルの作成
他の開発者が作成したHooksは、ライブラリとしてインストール(以下に示す) として使用することもできる. https://nikgraf.github.io/react-hooks/ https://github.com/rehooks/awesome-react-hooks 応答でHooksモードを使用すると、クラス構成部品を作成することなく機能の大部分 を実現できます.マニュアルでは、新しく作成した構成部品に関数構成部品とHooksを使用することを推奨しています. 以降の開発プロジェクトの場合は、関数型素子を使用することを第一の選択肢とし、必要に応じてクラス素子 のみを実施する.
また、ユーザ状態管理機能や、レンダリング後のタスクのユーザ効果->既存の関数構成部品ではできない機能も用意されています.より多くの作業を支援
応答内蔵Hooks->カスタムHooksの作成
まず、端末でcreate-act-appを使用して新しいプロジェクトを作成します。
yarn create react-app hooks-tutorial
ダメな場合↓
npm create react-app hooks-tutorial
8.1ユーザーステータス(3章参照)
useState機能によるデジタルカウンタの実装
import React, { useState } from "react"; //useState는 코드 상단에서 import 구문을 통해 불러옴
const Counter = () => {
const [value, setValue] = useState(0); // 이와 같이 사용 -> 파라미터에는 상태의 기본값인 '0'을 설정하여 넣어준다
// 그 배열의 첫 번째 원소는 상태 값, 두 번째 원소는 상태를 설정하는 함수
return (
<div>
<p>
현재 카운터 값은 <b>{value}</b> 입니다.
</p>
<button onClick={() => setValue(value + 1)}>+1</button>
<button onClick={() => setValue(value - 1)}>-1</button>
</div>
);
};
export default Counter; // 호출시 배열을 반환한다
この関数にパラメータを追加し、呼び出し時に渡されるパラメータに値を置き換えます->構成部品が正常にレンダリングされます
App.jsをレンダリングします^^
import React from "react";
import Counter from "./Counter";
const App = () => {
return <Counter />;
};
export default App;
// 터미널에 1. 또는 2. 입력 하여 개발서버 구동
// 1. yarn start
// 2. npm start
8.1.1複数使用usState
1つのuseState関数で管理できるのは->1つのステータス値のみです
複数のステータスを管理する必要がある場合は?->複数使用useState
srcディレクトリのInfo.jsファイルの作成
import React, { useState } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
// 다음과 같이 useState를 여러개 사용하여 관리할수 있음
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickname = (e) => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
import React from "react";
import Info from "./Info";
const App = () => {
return <Info />;
};
export default App;
8.2 useEffect
userEffectって何ですか?^^
反応素子をレンダリングするたびに特定の操作を実行するように設定できるHook.
クラス構成部品の構成部品DidMount+構成部品DidUpdate=UserEffect
import React, { useState, useEffect } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log("렌더링 완료 ~ !");
console.log({
name,
nickname,
});
});
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickname = (e) => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
8.2.1マウント時のみ実行
import React, { useState, useEffect } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log("마운트될 때만 실행됩니다.");
}, []); // useEffect 코드를 다음과 같이 변경
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickname = (e) => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
// 콘솔창에 한번만 실행된다.
8.2.2特定値の更新時のみ実行
useEffectを使用する場合、一部の値が変更された場合にのみ呼び出されますか?
クラスエレメントなら?
componentDidUpdate(prevProps, prevState) {
if (prevProps.value !== this.props.value) {
doSomething();
}
}
// props 안에 들어 있는 value 값이 바뀔 때만 특정 작업을 수행함
userEffectに渡される2番目のパラメータの配列に、チェックしたい値を入れます.
import React, { useState, useEffect } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log(name);
}, [name]); // useEffect 코드를 다음과 같이 수정
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickname = (e) => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
// 콘솔창에 한번만 실행된다.
8.2.3整理
デフォルトでは、userEffectはレンダリング直後に実行されます.
実行条件は、2番目のパラメータ配列に何を配置するかによって異なります.
構成部品をアンインストールまたは更新する前に、どのような操作を行いますか?userEffectはクリーンアップ関数(cleanup)を返します.
useEffectセクションを変更するには、次の手順に従います.
import React, { useState, useEffect } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log("effect");
console.log(name);
return () => {
console.log("Cleanup");
console.log(name);
};
}); // useEffect 코드를 다음과 같이 수정
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickname = (e) => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
// 콘솔창에 한번만 실행된다.
import React, { useState } from "react";
import Info from "./Info";
const App = () => {
const [visible, setVisible] = useState(false);
return (
<div>
<button
onClick={() => {
setVisible(!visible);
}}
>
{visible ? "숨기기" : "보이기"}
</button>
<hr />
{visible && <Info />}
</div>
);
};
export default App;
// 컴포넌트가 나타날시 -> 콘솔에 effect
// 컴포넌트가 사라질때 -> 콘솔에 cleanup
レンダリングするたびに、ポストアレンジ関数が表示されます.
呼び出し後の整理関数の表示時に更新される前の値
アンインストール時にクリーンアップ関数だけを呼び出したい場合は?
userEffect関数の2番目のパラメータに空の配列を追加
useEffect(() => {
console.log("effect");
console.log(name);
return () => {
console.log("Cleanup");
console.log(name);
};
}, []); // 두번째 파라미터에 비어있는 배열 추가
8.3 useReducer
userreducerとは?
Hook(17章減速機の概念を参照)は、素子によって異なる状態を異なる値に更新するために使用される.
Reducerとは?
現在のステータスと更新に必要な情報を含むアクション値を渡し、関数->不変性を維持
function reducer(state, action) {
return { … }; // 불변성을 지키면서 업데이트한 새로운 상태를 반환
}
{
type: ‘INCREMENT‘,
// 다른 값들이 필요하다면 추가로 들어감
}
8.3.1実施カウンタ
import React, { useReducer } from "react";
function reducer(state, action) {
// action.type에 따라 다른 작업 수행
switch (action.type) {
case "INCREMENT":
return { value: state.value + 1 };
case "DECREMENT":
return { value: state.value - 1 };
default:
// 아무것도 해당되지 않을 때 기존 상태 반환
return state;
}
}
const Counter = () => {
const [state, dispatch] = useReducer(reducer, { value: 0 }); // 첫번째 파라미터에는 리듀서 함수, 두번째 파라미터에는 해당 리듀서의 기본값을 넣어줌
// state는 현재 가리키고 있는상태
// dispatch는 액션을 발생시키는 함수 -> ex) dispatch(action)함수 내 파라미터로 액션 값을 넣어주면 리듀서 함수가 호출
return (
<div>
<p>
현재 카운터 값은 <b>{state.value}</b> 입니다.
</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>+1</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>-1</button>
</div>
);
};
export default Counter;
import React from "react";
import Counter from "./Counter";
const App = () => {
return <Counter />;
};
export default App;
8.3.2入出力状態の管理
usereducer->Infoコンポーネントの入力ステータスの管理
usereducerを使用する場合->入力ラベルにname値->e.targetを指定します.タスクは、name->Stateの設定と同様に処理されます.
Info.jsは以下のように変更されます.
import React, { useReducer } from "react";
// useReducer에서의 액션은 그 어떤 값도 사용 가능
function reducer(state, action) {
return {
...state,
[action.name]: action.value,
};
}
const Info = () => {
const [state, dispatch] = useReducer(reducer, {
name: "",
nickname: "",
});
const { name, nickname } = state;
const onChange = (e) => {
dispatch(e.target); // 액션값으로 e.target 값 자체를 사용
};
return (
<div>
<div>
<input name="name" value={name} onChange={onChange} />
<input name="nickname" value={nickname} onChange={onChange} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임: </b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
8.4 useMemo
なぜusemoを使うのですか?
import React, { useState } from "react";
const getAverage = (numbers) => {
console.log("평균값 계산 중..");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
// getAverage 함수가 호출되는 것을 확인할 수 있음
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = (e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {getAverage(list)}
</div>
</div>
);
};
export default Average;
import React from "react";
import Average from "./Average";
const App = () => {
return <Average />;
};
export default App;
usemo hook->最適化タスクの使用
レンダー中に値の一部が変化した場合にのみ実行->演算
Average.jsファイルの変更
import React, { useState, useMemo } from "react";
const getAverage = (numbers) => {
console.log("평균값 계산 중..");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = () => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
// list 배열의 내용이 바뀔때만 getAverage 함수가 호출
8.5 useCallback
useCallbackとは?
userMemoによく似た関数
レンダリングのパフォーマンスを最適化する必要がある場合に使用
イベントハンドラ関数が必要な場合にのみ作成できます
import React, { useState, useMemo, useCallback } from "react";
const getAverage = (numbers) => {
console.log("평균값 계산 중..");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = useCallback((e) => {
//첫번째 파라미터에는 생성하고 싶은 함수, 두번째 파라미터에는 배열을 넣음
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링될 때만 함수생성
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
}, [number, list]); //number 혹은 list가 바뀌었을 때만 함수 생성
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
// 위 아래 같은 코드라고 할 수 있음
useCallback(() => {
console.log("hello world!");
}, []);
useMemo(() => {
const fn = () => {
console.log("hello world!");
};
return fn;
}, []);
8.6 useRef
userefとは?
import React, { useState, useMemo, useCallback, useRef } from "react";
const getAverage = (numbers) => {
console.log("평균값 계산 중..");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const inpuyEl = useRef(null);
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링될 때만 함수생성
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
}, [number, list]); //number 혹은 list가 바뀌었을 때만 함수 생성
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange}ref={inputEl} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
8.6.1ローカル変数の使用
他の構成部品のローカル変数を使用する場合、ユーザーはRefを使用できます.
ローカル変数とは?
レンダリングを考慮せずに変更可能な値を示します.
クラス形式で作成された構成部品の場合->ローカル変数を使用する必要がある場合
import React, { Component } from 'react';
class MyComponent extends Component {
id = 1
setId = (n) => {
this.id = n;
}
printId = () => {
console.log(this.id);
}
render() {
return (
<div>
MyComponent
</div>
);
}
}
export default MyComponent;
import React, { useRef } from 'react';
const RefSample = () => {
const id = useRef(1);
const setId = (n) => {
id.current = n;
}
const printId = () => {
console.log(id.current);
}
return (
<div>
refsample
</div>
);
};
export default RefSample;
8.7カスタムホームページの作成
以前にInfoコンポーネントによって作成された複数の入力を管理するためのReducerを使用する論理を->Inputsを使用するHookに分離する
useInputs.jsファイルの作成
import { useReducer } from 'react';
function reducer(state, action) {
return {
...state,
[action.name]: action.value
};
}
export default function useInputs(initialForm) {
const [state, dispatch] = useReducer(reducer, initialForm);
const onChange = e => {
dispatch(e.target);
};
return [state, onChange];
}
↓Info素子使用import React from 'react';
import useInputs from './useInputs';
const Info = () => {
const [state, onChange] = useInputs({
name: '',
nickname: ''
});
const { name, nickname } = state;
return (
<div>
<div>
<input name="name" value={name} onChange={onChange} />
<input name="nickname" value={nickname} onChange={onChange} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임: </b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
8.8その他のhooks
8.9定理
Reference
この問題について([反応技術]第8章Hooks), 我々は、より多くの情報をここで見つけました https://velog.io/@uiop01900/8장-Hooksテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol