카테고리 없음

CRUD 벨로퍼트 공부 11-15 반복학습 ing.. 누가읽냐

김가마 2023. 3. 14. 22:28

코드 나누기 crud 

 

 


최종코드

import React, { useRef, useState } from "react";
import CreateUser1 from "./CreateUser1";
import UserListT from "./UserListT";

export default function APP1() {
  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: "ioi",
      email: "username@gmail.com",
    },
    {
      id: "2",
      username: "blackPink",
      email: "howulikeThat@gmail.com",
    },
    {
      id: "3",
      username: "BibI",
      email: "bad_bitch@gmail.com",
    },
  ]);
  //   ref 설정 추가
  const nextId = useRef(4);
  //   create; - 새로운 객체 안에 {}이이디값 유저네임이메일 새롭게 줘야함
  //   setUsers 에 바뀐 값 객체 newid값줘야함
  //   setInputs 에도 바뀌면 초기화 ' 빈값' 만들어주기
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    setUsers(users.concat(user));

   
    //
    setInputs({
      username: "",
      email: "",
    });
    //
    nextId.current += 1;
  };

  // 지우는 리무브
  const onRemove = (id) => {
    setUsers(users.filter((a) => a.id !== id));
  };

  const onToggle = (id) => {
    setUsers(
      users.map((user) =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };
  return (
    <>
      <CreateUser1
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserListT users={users} onRemove={onRemove} onToggle={onToggle} />
    </>
  );
}

1. 인풋 관리

  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });

  const { username, email } = inputs;

inputs값 useState로 문자열 상태관리하기

비구조할당으로 inputs 관리하기

객체를변화시키고 싶은 경우에는 기존 객체를 수정하지 않고 , 새로운 객체를 만들어서 수정해야한다.

inputs 개수만큼 useState 를 만들기에는 너무 비효율적임. 그래서 비구조할당을 이용해

원하는 변수를 꺼낸 뒤에 처리한다.

2. onchange 함수 만들기

 const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  onChange 함수 
  객체 e를 파리미터로 받아와서 
  이벤트 타켓에서 name, value 추출함 
  
  setInputs 세터 함수에게
  ...inputs 복사 
  [name]name 키를 가진 값을 : value로 설정함

input에 name을 성정하고 e.target 이벤트가 발생했을 때 이값을 참조 

useState 에서는 문자열이 아니라 객체 형태의 상태를 관리한다


setInputs ( 리액트에서 객체를 업데이트하게 될 때에는 기존 객체를 직접 수정하면 안되고,

새로운 객체를 만들어서, 새 객체에 변화를 주어야 함—-


★ useRef 

리액트를 사용하는 프로젝트에서도 가끔씩 DOM 을 직접 선택해야 하는 상황이 발생 할 때도 있습니다.

포커스를 잡으려면 nameInput.current.focus() 형태로 작성하면 된다.

const nameInput = useRef();
지우고 싶은 함수라서 

const onRemove = () => {
    setInputs ({
        name:'',
        nickname:'',
    })
    nameInput.current.focus();
네임인풋.가르킨다(현재DOM을) 인풋onRemove에 DOM API를 호출해
  }
현재 인풋 돔을 가르켜서 onRemove지우는 함수에 dom을 발생해서 api를 호출한다.

★배열의 렌더링

function UserList() {
  const users = [
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ];

배열의 인덱스를 하나하나 조회해가면서 렌더링하는 방법은 동적인 배열을 렌더링 하지 못해!

 

✅동적인 배열을 렌더링해야 할 때에는 자바스크립트 배열의 내장함수 map()  을 사용합니다

return (
    <div>
      {users.map(i => (
        <User i={user} />
      ))}
    </div>
i는 배열의 모든 원소 
ㄱ그러니까 users에 있는 객체들을 말하는거야

그리거고 무조건 키 값을 부여해야해

여기는 리액트 ✅! 리액트에서 배열을 렌더링 하려면 key라는 props를 설정해줘야해

✅key값은 각 원소들마다 가지고 있는 고유값으로 설정을 해야합니다. 지금의 경우엔 id가 고유 값이지요.

<User item={user} key={user.id} />

만약에 배열을 렌더링 할 때 key설정을 하지 않게된다면 ✅

기본적으로 배열의 index값을 key  로 사용하게 되고, 아까 봤었던 경고메시지가 뜨게 됩니다.

array.map(item => <div key={item.id}>{item}</div>
key 값이 있으면 수정되지 않은 기존값은 그대로 두고
✅바꾸고 싶은 내용을 삽입 , 삭제 가능

useRef 조회, 수정 역할 .2 

아까는 이것은 특정한 돔을 가르키키 위해 쓴다했다.

그리고 함수형 컴포넌트에서 이를 설정할때 useRef를 사용해서 설정한다고 했다.

DOM을 선택하는 용도 이외에도… 다른 용도가 하나 더있다..

바로 컴포넌트 안에서 조회 및 수정 할수 있는 변수를 관리하는 것이다.

  • setTimeout, setInterval 을 통해서 만들어진 id
  • 외부 라이브러리를 사용하여 생성된 인스턴스
  • scroll 위치

 

그럼 useRef를 조회 및 수정할 변수의 목적으로 사용해보자

새항목에서 사용할 고유한 id관리 용도

✅배열을 App 에서 선언하고 UserList 에게 props 로 전달을 해주겠습니다.

import React from 'react';

import UserList from './UserList';

function App() {
  const users = [
    {
      id: 1,
      username: 'velopert',
      email: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
app 컴포넌트 안에 users라는 배열에 3개 객체를 담고 있어 
각 객체 는 id, username, email있다.
  ];
  return <UserList users={users} />;
return
}  {users}라는 객체들을 userList 컴포넌트 안에 users라는 props로 전달해서 렌더링한다.
   UserList 컴포넌트를 렌더링하여 items props로 전달된 users 배열에 담긴 객체들을
 목록 형태로 화면에 출력하는 역할을 합니다.



export default App;
UserList 컴포넌트야!!

export function User({ user }) {
  return (
    <div>
      <b>{user.username}</b>
      <span>({user.email})</span>
    </div>
  );
}
user 컴포넌트에 user props 전달받아서 
사용자 정보 user,유저네임/ 이메일을 가져오는거임 

function UserList({ users }) {
  return (
    <div>
      {users.map((item) => (
        <User item={user} key={user.id} />
      ))}
    </div>
  ); item 이름 각 [] 배열의 원소의 이름! 
유저리스트 컴포넌트에 {users} props으로 가져옴 ? 전달받은 사용자 정보객체들을 !
각 객체들을 map 을 사용해 item에 전달해줘 . 키는 props 라는 user컴포넌트가 렌더링할때
각각 컴포넌트를 구분하기위해 고유한 값으로 사용해

item 이름 작명 가능 | 각 배열의 원소 


nextId.current는 함수가 호출될 때마다 4입니다.

useRef Hook 은 DOM 을 선택하는 용도 외

컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리

  • *useRef 로 관리하는 변수는 값이 바뀌어도 컴포넌트 리렌더링 X

 

📌배열 항목 추가하기

이 값을 수정 할때에는 .current 값을 수정, && 조회 할 때에는 .current 를 조회

const nextId = useRef(4);초기값 설정 , 추가 할떄 쓰는 함수
nextId 변수는 useRef 훅을 이용하여 4라는 초기값으로 설정되어 있습니다.
 useRef는 함수형 컴포넌트에서 상태 값을 유지할 때 사용됩니다. 
nextId 변수는 이후에 새로운 사용자를 추가할 때 사용됩니다.
추가 
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
onCreate 함수는 새로운 사용자 정보를 생성하는 역할을 합니다. 
이 함수는 현재 입력된 username과 email 값을 이용하여 user 객체를 생성합니다
유저user 라는  객체를 생성해
이 객체에 id 는 유저네임과네임을 포함하고 있어/

               ✅ 기존users배열과 + 새로 추가된 user객체 합하기
    setUsers([...users, user]); 추가된함수에 
setUsers를 함수를 이용해서 users 상테를 업데이트해!
setUsers 함수는 이전의 ...users 배열과 
새롭게 추가된 user 객체를 => + 합쳐서 새로운 배열을 생성합니다.
 이 배열은 이후에 UserList 컴포넌트에서 렌더링됩니다.

    setInputs({
      username: '',
      email: ''
    }); 인풋 값 입력된 값 -> 초기화
setInputs 함수를 이용하여 username과 email 상태를 초기화합니다.
 이전에 입력된 값은 모두 지워집니다.
    nextId.current += 1;
nextId.current 값을 증가시켜 다음에 추가될 사용자의 id 값이 겹치지 않도록 합니다.
  }; 

결과적으로 이 코드는 새로운 사용자 정보를 입력받고, 
입력된 정보를 이용하여 새로운 사용자 객체를 생성한 뒤, users 상태를 업데이트하여 UI에 반영하는 역할을 합니다.

📌배열에서 요소 지우기

→id매개변수를 받아와서 filter()메소드를 사용하여

users 배열에서 user.id가 id와 일치하지 않는 원소만 추출하여 새로운 배열을 만들고,

이를 새로운 users 상태로 설정합니다. 즉, **id**와 일치하는 **user.id**를 제거하는 역할을 합니다.

const onRemove = id => {
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  }; 한국어로 설명좀
(user => user.id !== id)); 유저아이디!==id  
✅user배열에서 => user.id 가 id와 일치 하지 않는 것만 추출해서 새로운[] 배열로 담고!
필터는 특정한 조건을 설정해 새로운배열로 담는것 
담은 그상태에 users.filter 에게 상태로 설정해줘
users 한테 야 그럼 id와 일치하는 user.id를제거해

  const onToggle = (id) => {
    setUsers(
      users.map((user) =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };


이 코드는 onToggle 함수로, id 매개변수를 받아와서 
users 배열에서 해당 id와 일치하는 객체를 찾아 
active 값을 반전시킨 새로운 배열을 생성하여 상태로 설정하는 역할을 합니다.

map() 메소드는 배열을 순회하며,
 각 요소를 새로운 값으로 변환하여 새로운 배열을 생성합니다.
 반복 
이 코드에서는 users 배열을 순회하면서 각 요소의 id가 id 매개변수와 일치하는 경우,
 ✅active 값을 반전시킨 객체를 생성하고, 그렇지 않은 경우는 그대로 유지합니다.


 { ...user, active: !user.active }는 객체 스프레드 연산자를 사용하여 user 객체를 복사하고,
 active 속성만 반전시킨 새로운 객체를 생성합니다. 
따라서 user.id === id인 경우에는 새로운 객체가 생성되고, 
그렇지 않은 경우에는 기존 user 객체가 그대로 사용됩니다
마지막으로, setUsers() 함수를 사용하여 새로운 배열을 users 상태로 설정합니다.

 이렇게 함으로써 해당 id의 active 값을
user.id === id가 참일 경우, { ...user, active: !user.active }가 실행되고, 
active 속성값이 반전된 객체가 생성됩니다. 
!