かっこいい学習記録-03Hooks

25364 ワード

Hooks



1. useState


state=>構成部品内で変更可能な値(データ).直接変更できません
import React, { useState } from "react";

const InputPractice = () => {
  const [inputs, setInputs] = useState({
    name: "",
    nickname: "",
  });

  const { name, nickname } = inputs;

  const onChange = (e) => {  
    const { value, name } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };

  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
  };

  return (
    <div>
      <input name="name" placeholder="이름" onChange={onChange} value={name} />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
};

export default InputPractice;
以下のコードのonChangeでは[name] : valueと呼ぶ.
既存のオブジェクトに関係なく新しいオブジェクトを作成するためのJSのspread構文を使用してstateの不変性を実現します.
すなわち、既存のstateをコピーし、新たに追加されたnameというキー値に設定する.inputs[name] = valueのように直接修正することはできません

2. useRef


純JSを使用する場合、特定のDOMを選択するために、
getElementByIdやquerySelectorなどのDOMセレクタ関数を使用します.
反応器はref、関数タイプはuseref、クラスタイプはコールバック関数またはreactを使用します.createRefという名前の関数を使用します.
次に、Inputウィンドウでuserefを使用する例を示します.
import React, { useRef, useState } from "react";

const InputPractice = () => {
  const [inputs, setInputs] = useState({
    name: "",
    nickname: "",
  });
  const nameInput = useRef();

  const { name, nickname } = inputs;

  const onChange = (e) => {
    const { value, name } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
    // inputs[name] = value;
  };

  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
    nameInput.current.focus();
  };

  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
};

export default InputPractice;

3.配列

  • App.js
  • import React, { useRef, useState } from "react";
    import CreateUser from "./components/CreateUser";
    import UserList from "./components/UserList";
    
    const App = () => {
      const [inputs, setInputs] = useState({
        username: "",
        email: "",
      });
      const { username, email } = inputs;
      const onChange = (e) => {
        const { name, value } = e.target;
        setInputs({
          ...inputs,
          [name]: value,
        });
      };
      const [users, setUsers] = useState([
        {
          id: 1,
          username: "velopert",
          email: "[email protected]",
        },
        {
          id: 2,
          username: "tester",
          email: "[email protected]",
        },
        {
          id: 3,
          username: "liz",
          email: "[email protected]",
        },
      ]);
    
      const nextId = useRef(4);
      const onCreate = () => {
    		/* 로직 추가 필요 */
    
        setInputs({
          username: "",
          email: "",
        });
        nextId.current += 1;
      };
    
      return (
        <>
          <CreateUser
            username={username}
            email={email}
            onChange={onChange}
            onCreate={onCreate}
          />
          <UserList users={users} />
        </>
      );
    };
    
    export default App;
  • CreateUser.js
  • import React from "react";
    
    const CreateUser = ({ username, email, onChange, onCreate }) => {
      return (
        <div>
          <input
            name="username"
            placeholder="계정명"
            onChange={onChange}
            value={username}
          />
          <input
            name="email"
            placeholder="이메일"
            onChange={onChange}
            value={email}
          />
          <button onClick={onCreate}>등록</button>
        </div>
      );
    };
    
    export default CreateUser;
  • UserList.js
  • 
    const User = ({ user }) => {
      return (
        <div>
          <b>{user.username}</b> <span>({user.email})</span>
        </div>
      );
    };
    
    const UserList = ({ users }) => {
      return (
        <div>
          {users.map((user) => (
            <User user={user} key={user.id} />
          ))}
        </div>
      );
    };
    
    export default UserList;

    3-1. 追加


    宣言配列は2479142→直接修正後
    JS配列関数のstatepushなどは配列を直接修正します!
    したがって、以前に学習したspread構文を使用するか、splice関数を使用することができる.
  • App.js - onCreate - spread
  • const onCreate = () => {
      const user = {
        id: nextId.current,
        username,
        email
      };
      setUsers([...users, user]);
    
      setInputs({
        username: '',
        email: ''
      });
      nextId.current += 1;
    };
  • App.js - onCreate - concat
  • const onCreate = () => {
      const user = {
        id: nextId.current,
        username,
        email
      };
      setUsers(users.concat(user));
    
      setInputs({
        username: '',
        email: ''
      });
      nextId.current += 1;
    };

    3-2. 削除

  • UserList.js→各アイテム追加削除ボタン
  • import React from 'react';
    
    function User({ user, onRemove }) {
      return (
        <div>
          <b>{user.username}</b> <span>({user.email})</span>
          <button onClick={() => onRemove(user.id)}>삭제</button>
        </div>
      );
    }
    
    function UserList({ users, onRemove }) {
      return (
        <div>
          {users.map(user => (
            <User user={user} key={user.id} onRemove={onRemove} />
          ))}
        </div>
      );
    }
    
    export default UserList;
    import React from 'react';
    
    const User = ({ user, onRemove }) => {
      return (
        <div>
          <b>{user.username}</b> <span>({user.email})</span>
          <button onClick={() => onRemove(user.id)}>삭제</button>
        </div>
      );
    }
    
    const UserList = ({ users, onRemove }) => {
      return (
        <div>
          {users.map(user => (
            <User user={user} key={user.id} onRemove={onRemove} />
          ))}
        </div>
      );
    }
    
    export default UserList;
  • App.js - onRemove
  • const onRemove = id => {
      // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
      // = user.id 가 id 인 것을 제거함
      setUsers(users.filter(user => user.id !== id));
    };

    3-3. 変更

  • App.js→users state
  • にアクティブキーを追加
    const [users, setUsers] = useState([
      {
        id: 1,
        username: 'velopert',
        email: '[email protected]',
        active: true
      },
      {
        id: 2,
        username: 'tester',
        email: '[email protected]',
        active: false
      },
      {
        id: 3,
        username: 'liz',
        email: '[email protected]',
        active: false
      }
    ]);
  • App.js - onToggle
  • const onToggle = id => {
      setUsers(
        users.map(user =>
          user.id === id ? { ...user, active: !user.active } : user
        )
      );
    };
  • UserList.js
  • import React from 'react';
    
    const User = ({ user, onRemove, onToggle }) => {
      return (
        <div>
          <b
            style={{
              cursor: 'pointer',
              color: user.active ? 'green' : 'black'
            }}
            onClick={() => onToggle(user.id)}
          >
            {user.username}
          </b>
          &nbsp;
          <span>({user.email})</span>
          <button onClick={() => onRemove(user.id)}>삭제</button>
        </div>
      );
    }
    
    const UserList = ({ users, onRemove, onToggle }) => {
      return (
        <div>
          {users.map(user => (
            <User
              user={user}
              key={user.id}
              onRemove={onRemove}
              onToggle={onToggle}
            />
          ))}
        </div>
      );
    }
    
    export default UserList;

    4. useEffect


    素子の多くは以下の3つの場合に更新される.
  • 道具変換時
  • 状態遷移時
  • 親構成部品の再レンダリング時
  • クラス構成部品には、条件を満たす構成部品を処理する場合に使用するライフサイクルメソッドがあります.(concatcomponentDidMountcomponentDidUpdate等)
    関数要素にはライフサイクルメソッドがなく、componentWillUnmount hookを使用して同じ機能を実現できます.
    useEffect(() => {
    	// 함수 내용
    }, [deps])
    useEffect  使用する場合、最初のパラメータは関数です.
    2番目のパラメータは依存値を含む配列(useEffect)である.
    万一.  deps  空の配列の場合、構成部品が初めて表示される場合のみ  deps  に登録されている関数を呼び出します.useEffect  関数を返すことができます.  useEffect  関数と呼びます. cleanup  関数は  cleanup  正しいまとめとして.useEffect  空の場合、構成部品は消えます.  deps  関数が呼び出されます.

    5. useMemo


    内部特定値演算のhookを最適化できます.

    6. useCallback


    App.jsのcleanup、  onCreateonRemove  構成部品を再レンダリングするたびに、新しい関数が作成されます.
    構成部品を頻繁にレンダリングする場合、またはレンダリングする構成部品の数が多すぎる場合は、最適化する必要があります.
    関数に使用されている状態やpropsがある場合は、  onToggle  配列に含めるべきです!