[React] 8. react-hooks(useState, useEffect, useRef)


HooksはReact 16.8に追加されました.
以前は、関数構成部品でステータスを管理するためにクラス構成部品を再作成する必要がありましたが、Hooksが発生した場合、関数構成部品もステータスにすることができます.このほか、Hooksはさまざまな機能を提供しています.
関数型素子を状態にすると、クラス素子を使用する回数よりも関数型素子を使用する回数が多くなります.
しかし,Hooksの導入は,以前に学習した反応に関する概念を必要としないという意味ではない.Hooksは、既知のprops、state、context、refs、lifecycleなどのより直接的なAPIを提供しているだけです.
これはHooksがclassではなくstateや他のReact機能を使用することを意味します.
次の公式文書を参照してください.
https://reactjs.org/docs/hooks-intro.html

Hooks Api


次に、Hooks APIを見てみましょう.

1. useState


useStateは関数素子にstateを持たせるhookである.
const [state, setState] = useState(initialState);
useStateは、2つの要素を含む配列を返します.1番目の要素は要素の現在の状態であり、2番目の要素は状態を設定できる関数です.
userStateのパラメータは状態の初期値を表します.
初期値が設定されているため、最初のログイン後はパラメータは無視されます.
function App() {
// useState를 사용하여 count라는 state를 생성 초기값은 0으로
  const [count, setCount] = useState(0);
  const add = () => {setCount(count+1);}//setCount로 state값 변경
  const min = () => {setCount(count-1);}
  return (
    <div>
      <p>Current COUNT : {count}</p>
  	  <button onClick={add}>+</button>
      <button onClick={min}>-</button>
    </div>
  );
}

2. useEffect


userEffectはHookで、反応素子をレンダリングするたびに特定の操作を実行するように設定できます.クラス要素のコンポーネントDidMountとコンポーネントDidUpdateを組み合わせることもできます.
useEffectを適用しましょう.
function App() {
  const [count, setCount] = useState(0);
  const add = () => {setCount(count+1);}
  const min = () => {setCount(count-1);}
  useEffect(() => {
    console.log('마운트 될 때만 실행됩니다.');
  });
  return (
    <div>
      <p>Current COUNT : {count}</p>
  	  <button onClick={add}>+</button>
      <button onClick={min}>-</button>
    </div>
  );
}
export default App;
ボタンをクリックしてステータスを変更すると、再ロードされ、userEffectが燃えていることが表示されます.
useEffectのマウント時にのみ実行する場合は、2番目のパラメータに空の配列を配置して、最初のパラメータでのみ発生し、その後のレンダリングでは発生しないことを確認します.
useEffect(() => {
console.log(“Landering~”);
},[]);
特定の値なしでのみ実行する場合は、2番目のパラメータに特定の値を追加できます.

3. useRef


userefを使用してrefを設定すると、userefによって作成されたオブジェクトの現在の値が実際の別名を指します.
イベント発生時e.target.userefを使用して値をインポートできます.
function App() {
  const textRef = useRef();
  const changeE = (e)=>{
    let eValue = e.target.value;
    let refValue = textRef.current.value;
    console.log(eValue,refValue);
  }
  return (
    <div>
      <input type = "text" ref= {textRef} onChange = {changeE}></input>
    </div>
  );
}
export default App;
テキストボックスを入力すると、「開発者ツールコンソール」ウィンドウに表示される値は同じです.
この3つのhooksapiを使用してテキストを入力して追加すると、リストに追加するとカウントされ、リストに追加するデータをクリックするとカウントが減少する例を作成します.ファイルには、App、Header、List、Item、およびItemが含まれる.cssには5つのファイルがあります.
Item.css
Item.cssファイルを作成します.
画面にやるべきことのリストjs学習を追加し、reactをクリックして変更する用途です.
.done {
text-decoration: line-through;
font-style: italic;
}
App.js
import List from './List.jsx';
import React, { Component, useState, useEffect } from 'react';
import Header from './Header.jsx';
import Form from './Form.jsx';
export const TodoContext = React.createContext();
const App = () => {
  //useState를 사용하여 state 생성, 초기값 지정
  const [state, setState] = useState([
    {"id" :"js공부", "status" : "re"},
    {"id" :"react", "status" : "re"}]); 
  const[newTodo, setNewTodo] = useState();//useState를 사용하여 newTodo 생성 초기값 없음
  const changeInputData = (e) =>{ // onChange 이벤트 발생 시 NewTodo에 해당 값 저장
    setNewTodo(e.target.value);
  }
  const addTodo = (e) => {  // onClick 이벤트 발생 시 state에 해당 값 저장
    e.preventDefault();
    setState([...state, {id : newTodo, status : 're'}]);
  }
  const changeT = (id) => { // 할 일 목록 내 item을 클릭 시 발생하는 이벤트 클릭 시 해당 값에 변화를 주기 위함
    const updateT = state.map(todo =>{
      if(todo.id === id){
        if(todo.status === 'done') todo.status= 're';
        else todo.status = 'done';
      }
      else{
      }
      return todo; 
    });
    setState(updateT);
 }
 useEffect( () =>{  //랜더링 될 때 호출
    console.log('새로운 내용이 랜더링됐네요', state);
   }, [state]); // 특정값 state에 지정하였기 때문에 newTodo가 변경될때는 타지 않음
  return (
    <>
      <Header state = {state}></Header>
      <form action="">
        <input type="text" name="" onChange={changeInputData} />
        <button onClick={addTodo}>할일추가</button>
      </form>
      <List todos= {state} changeT = {changeT}></List>
    </>
  )
}
export default App;
Header.jsx
ここには、実行するタスクのリスト数が表示されます.
filter()関数を使用して、パラメータ値を返すstatのステータス値のみを「re」として計算します.
import React, { useMemo } from "react";
import { TodoContext } from "./App.js";
const Header = ({ state }) => {
  const count = (state) => {
    let cnt = state.filter((v) => v.status === "re").length;
    return cnt;
  };
  return (
    <div>
      <h1>Hooks를 사용한 예제</h1>
      <div>갯 수 : {count(state)}개</div>
    </div>
  );
};
export default Header;
List.jsx
ここにはやるべきことがリストされています.
map()関数を使用して、親構成部品から渡されたパラメータ値をitemに渡します.
import Item from "./Item.jsx";
import React, { useContext } from "react";
import { TodoContext } from "./App.js";
const List = ({ todos, changeT }) => {
  let todoList = todos.map((todo) => (
    <Item todo={todo} changeT={changeT}></Item>
  ));
  return (
    <div>
      <ul>할 일 목록{todoList}</ul>
    </div>
  );
};
export default List;
item.jsx
ここでは、パラメータ値として受信したtodoのステータス値を確認することでcssを変更できます.
import "./item.css";
const Item = ({ todo, changeT }) => {
  const toggleItem = (e) => {
    const id = e.target.dataset.id;
    changeT(id);
  };
  let classNm = "";
  // status가 "done"인 경우 css를 입힐 수 있게 값을 저장합니다.
  if (todo.status === "done") {
    classNm = "done";
  } else {
    classNm = "";
  }
  return (
    <div>
      <li data-id={todo.id} className={classNm} onClick={toggleItem}>
        {todo.id}
      </li>
    </div>
  );
};
export default Item;
コードを作成して実行
hooksを入力し、「保留中の追加」ボタンをクリックします.
hooksが保留中のリストに追加され、数が増加していることがわかります.
また「hooks」をクリックすると
hooksでは,斜線のcssが正常であり,数が減少することが分かった.
3つのhooksapiを用いて例を作成した.
次に、残りのAPIを確認します.