React/Velopert's React

[React] Study #14 | 배열 항목 수정하기

yevdev 2021. 10. 7. 19:28

#12 배열에 항목 추가 , #13 배열의 항목 삭제에 이어서 하는 배열 항목 수정하기이다!

 

User 컴포넌트에 계정명을 클릭했을 때 색상이 초록색으로 바뀌고, 다시 누르면 검정색으로 바뀌는 기능을 구현해보자!

 

1️⃣ App 컴포넌트의 users 배열 안의 객체 안에 active라는 속성 추가

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(
    // active 속성 추가
    [
      {id: 1, username: 'John', email: 'john@example.com',
      active: true,
    },
      {id: 2, username: 'Car', email: 'car@example.com',
      active: false,
    },
      {id: 3, username: 'lee', email: 'lee@example.com',
      active: false,
    },
    ]
)
    

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 => {
  setUsers(users.filter(user => user.id !== id))
}

  return (   
    <>
      <CreateUser 
      username={username}
      email={email}
      onChange={onChange}
      onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
    </>
  );
}

export default App;

 

2️⃣ User 컴포넌트에서 active 값에 따라 폰트 색상 바꾸고 마우스를 올렸을 때 커서가 손가락 모양으로 바뀌도록!

  • active 속성 컨트롤 : 삼항연산자 이용
  • 손가락모양으로 커서 바꾸기 : cursor 속성 이용

UserList.js

import React from 'react'

function User({user, onRemove}) {
    return(
        <div>
            {/* style 안에 cursor, color을 이용해 기능 구현 */}
            <span
                style={{ 
                    cursor: 'pointer',
                    color: user.active ? 'green':'black',
                }}>{user.username}</span>
            &nbsp;
            <span>{user.email}</span>
            <button onClick={()=>onRemove(user.id)}>삭제</button>
        </div>
    )
}

function UserList({users, onRemove}) {

    return (
        <div>
            {/* 배열을 렌더링할때, key라는 props를 설정해주기!! */}
            {users.map(user => (
                <User user={user} key={user.id} onRemove={onRemove}/>
            ))}
        </div>
    )
}

export default UserList

 

 

3️⃣ onToggle 구현

  • 배열의 불변성을 유지하면서 업데이트 할 때에도 map 함수를 사용
  • id를 비교해서 id가 다르면 그대로 두고 같으면 active 값을 반전
  • UserList에 onToggle 함수 전달

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(
    // active 속성 추가
    [
      {id: 1, username: 'John', email: 'john@example.com',
      active: true,
    },
      {id: 2, username: 'Car', email: 'car@example.com',
      active: false,
    },
      {id: 3, username: 'lee', email: 'lee@example.com',
      active: false,
    },
    ]
)
    

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 => {
  setUsers(users.filter(user => user.id !== id))
}

const onToggle = id => {

  //user.id와 파라미터로 가져온 id가 같으면 active를 반전시킨다
  setUsers(
    users.map(user => 
      user.id === id ? { ...user, active: !user.active} : user
    )
  )
}

  return (   
    <>
      <CreateUser 
      username={username}
      email={email}
      onChange={onChange}
      onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
    </>
  );
}

export default App;

 

 

4️⃣  UserList컴포넌트에서 받아온 onToggle을 User에게 전달해주고, 파라미터로 id를 넣어 onToggle을 호출!

UserList.js

import React from 'react'

function User({user, onRemove, onToggle}) {
    return(
        <div>
            {/* id를 파라미터로 넘겨주기 */}
            <span
                style={{ 
                    cursor: 'pointer',
                    color: user.active ? 'green':'black',
                }}

                onClick={()=>onToggle(user.id)}
                >{user.username}</span>
            &nbsp;
            <span>{user.email}</span>
            <button onClick={()=>onRemove(user.id)}>삭제</button>
        </div>
    )
}

function UserList({users, onRemove, onToggle}) {

    return (
        <div>
            {users.map(user => (
                <User user={user} key={user.id} onRemove={onRemove} onToggle={onToggle}/>
            ))}
        </div>
    )
}

export default UserList

이름을 클릭하면 색이 변한다

 

 


Reference

https://react.vlpt.us/basic/15-array-modify.html