React 코드 구조 공부

김석·2023년 9월 7일
0

React

목록 보기
3/14

App.js

import React, { useRef, useState } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';

function 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: 'public.velopert@gmail.com'
    },
    {
      id: 2,
      username: 'tester',
      email: 'tester@example.com'
    },
    {
      id: 3,
      username: 'liz',
      email: 'liz@example.com'
    }
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

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

  const onRemove = id => {
    // user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
    // = user.id 가 id 인 것을 제거함
    setUsers(users.filter(user => user.id !== id));
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} />
    </>
  );
}

export default App;

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;

CreateUser.js

import React from 'react';

function 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;

순서

  1. App.js가 실행됨.
  2. 순서대로 실행되며 값과 함수들이 선언됨
  3. return 부분이 렌더링되고, 컴포넌트들에 콜백 함수가 등록됨
  4. 구조상 중요한 게, 여기서 UserList이랑 CreateUser 컴포넌트를 렌더링하는데, 얘네 안에 있는 버튼을 클릭할 때 실행되는 함수를 App.js에서 정의하고, 콜백 함수로 함수만 넘겨줌.
  5. 함수를 컴포넌트 내부에 정의하는게 아님. 함수를 App.js에서 정의하고 넘겨주기만 하는게 핵심
  6. 이게 사실 당연한게, 상태는 App.js에 저장되어 있음. onCreate, onRemove는 이 상태를 변경시켜줘야 함. 그래서 당연히 여기에 정의하고 넘겨주는게 맞음.
  7. onCreate는 매개변수를 받지 않는게 당연하고, onRemove는 매개변수로 id를 받아서 지워야 함
  8. 여기서 삭제 버튼은 모든 User 컴포넌트에 있어야 함. UserList가 아니라.
  9. App.js에서는 UserList를 렌더링하고, UserList 안에서 각 User를 렌더링함.
  10. 각 User 컴포넌트에 삭제 버튼이 있고, 여기에 onRemove가 달려있어야 함.
  11. 그래서 App.js -> UserList로 onRemove 함수를 전달하고, UserList -> User로 onRemove함수가 전달됨.
  12. 지금 함수가 변수처럼 전달되는 구조이지, 실행되는 구조가 아님.
  13. 마찬가지로 button의 onClick prop에도 변수로서의 함수가 저장되어야 함.
  14. 근데 매개변수가 들어간 onRemove가 호출되어야 함.
  15. 따라서 {() => onRemove(user.id)}라고 콜백 함수를 등록함.

결론

  1. 상태 저장하는 js에, 그 상태를 변경하는 함수들을 선언
  2. 그 안에 여러 컴포넌트들이 조합되어 있을 건데, 적절하게 함수 전달해서 콜백 함수 등록
  3. 그러니까 컴포넌트에다가 해줘야 하는 것은, 렌더링할(상태 관리되는) 변수와, 어떤 버튼을 누르는 액션 같은 걸 취했을 때 수행할 콜백 함수를 등록하는 것

출처


https://react.vlpt.us/basic/14-array-remove.html

profile
handsome

0개의 댓글