목차 | |
1. | 배열 |
2. | 느낀 점 |
1. 배열
◈ 이론
■ array 랜더링 시 key의 존재 유무에 따라
업데이트, 삭제, 추가 시 효율적으로 랜더링 됨.
users.map((u,i)=>(
<User user={u} key={u.id}/>
))
■ useRef()로 컴포넌트 안의 변수 만들기
- 컴포넌트에서 특정 DOM을 선택할 때 사용
- 컴포넌트 안에서 조회, 수정을 할 수 있는 변수를 관리할 수 있음.
■ useRef()로 관린하는 변수는 값이 바뀐다고 하여
컴포넌트가 재랜더링 되지 않음.
■ useRef()를 통해 관리하는 값들...
- setTimeout / setInterval을 통해서 만들어지는 id
- 조회, 수정, 삭제 시 사용되는 id
- 외부 라이브러리를 사용하여 생성된 인스턴스
■ useRef() / useState() :
- 비슷하게 어떤 값을 저장하는 저장공간의 역할
- 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리
- useRef()로 관리하는 변수는 값이 바뀐다고 해도
컴포넌트가 재랜더링 되지 않음.
- state : 변화 => 랜더링 => 컴포넌트 내부 변수들 초기화
- ref : 변화 => 랜더링X => 내부 변수들 값 유지
- 변경 시 랜더링을 발생시키지 말아야 하는 값을 다룰 때 사용
- 변화는 감지해야 하지만, 그 변화가 랜더링을 발생시키지 않아야 할 때 사용
◈ 실습
- App.js
import './App.css';
import UserList from './component/UserList';
import StoreList from './component/StoreList';
function App() {
return (
<div className="App">
{ <UserList /> }
<br />
<hr />
{/* 맛집 리스트 추가 */}
{/* 월미당(쌀국수집) */}
{ <StoreList />}
</div>
);
}
export default App;
- CreateUser.jsx
=> username,email,onChange,onCreage을 변수로 받음 > name은 데이터의 이름, value는 화면에 표시되는 값, onChange는 input창이 입력할 때마다 정보를 저장하기 위해서 연결, onCreate는 button을 클릭할 때마다 배열에 정보를 넣기 위해서 연결함
import React from 'react';
const CreateUser = ({ username, email, onChange, onCreate }) => {
// const { username, email, onChange, onCreate } = props;
return (
<div className='createName'>
<input
type="text"
name='username'
placeholder='이름'
onChange={onChange}
value={username}
/>
<input
type="text"
name='email'
placeholder='이메일'
onChange={onChange}
value={email}
/>
<button onClick={onCreate}>create</button>
</div>
);
};
export default CreateUser;
- User.jsx
=> user의 username과 email를 가져옴(username, email 대신에 props를 활용할 수 있음) > User 함수가 실행될 때 user의 id 값을 onRemove의 파라미터에 전달함(언제든지 X버튼을 눌러도 전달했던 id값을 onRemove함수에게 전달하여 실행함) > span 태그를 이용하여 active가 true인지 false인지 삼항연산자를 통해서 색깔을 변경함
import React from 'react';
const User = ({ user, onRemove, onToggle }) => {
// const user = props.user;
return (
<div className='user'>
<h3>
<span style={{
cursor: 'pointer',
color: user.active ? 'green' : 'black'
}} onClick={() => onToggle(user.id)}> {user.username}</span>
<span>({user.email})</span>
{/* function으로 매개변수를 전달할 겨우 */}
<button onClick={() => onRemove(user.id)}>X</button>
</h3>
</div>
);
};
export default User;
- UserList.jsx
- nextId
=> useRef(n)를 nextId에 저장하여 input창에 입력된 값의 id가 n이 되도록 함
- onChange
=> useState는 계속 랜더링을 하기에 다른 input창을 입력하면 기존에 입력했던 input창의 데이터를 초기화됨 > 입력될 때마다 ...inputs로 기존의 값을 복사하고 key : value 형태인 [name] : value로 저장함(수정된 데이터만 업데이트되는 형식)
- onCreate
=> id : nextId.current로 id는 현재의 nextId라는 것을 정함(username과 email은 key와 value의 이름이 같은 경우이기에 value를 생략하여 적을 수 있음 (ex : username : username > username)) > concat을 이용하여 input창에 입력된 값을 배열에 저장함(추가되는 형식) > 기존 input창에 입력된 값을 초기화 > setUsers를 통해 id가 저장되었기에 nextId.current의 값을 +1를 해주어 다음 id로 생성될 수 있도록 세팅함
- onRemove
=> filter를 활용하여 파라미터를 받는 함수를 만듦 > User.jsx에 onRemove 버튼이 있기에 map을 실행할 때 onRemove를 연결함(filter는 조건에 부합한 원소만 추출함)
- onToggle
=> 삼항연산자를 통해 자신이 선택한 id가 같다면 active의 값를 반대로 바꾸고 id가 다르다면 기존의 값 그대로 setter 저장하며 setter가 useState로 저장되어있기에 기존의 값이 초기화가 됨 > spread를 통해서 기존의 값을 복사함
- return
=> key(=> id)값을 안 정해주면 console에서 오류가 나옴
import React, { useRef, useState } from 'react';
import User from './User';
import CreateUser from './CreateUser';
const UserList = () => {
const nextId = useRef(6);
const [users, setUsers] = useState([
{
id: 1,
username: 'kim',
email: 'kim123@naver.com',
active: true
},
{
id: 2,
username: 'lee',
email: 'lee123@naver.com',
active: true
},
{
id: 3,
username: 'park',
email: 'park123@naver.com',
active: false
},
{
id: 4,
username: 'choi',
email: 'choi123@naver.com',
active: false
},
{
id: 5,
username: 'hong',
email: 'hong123@naver.com',
active: false
}
]);
const [ inputs, setInputs ] = useState({
username : '',
email : ''
});
// 구조 분해 할당 : 객체의 구조를 분해하여 변수에 할당하는 방법
const { username, email } = inputs;
const onChange = (e) => {
const { name, value } = e.target;
// 변경되지 않은 대상값을 공백처리 => 기존값 유지
setInputs({
...inputs, // 기존 inputs 값을 복사
[name]:value // 현재 변경된 값을 key : value 형태로 set
});
console.log(inputs);
}
const onCreate = ()=>{
// 값이 추가되면...
// 나중에 여기서 구현
// .current : 현재값
const user = {
id: nextId.current,
username: username,
email: email
}
// 현재 users에 user 추가 => concat
setUsers(users.concat(user));
// 기존 inputs 창 초기화
setInputs({
username:'',
email:''
})
nextId.current += 1 ; //ref() : 재랜더링이 일어나지 않음
console.log(users);
}
const onRemove = (id) => {
// filter : 배열의 항목을 제거하기 위해서 사용
// filter는 조건에 맞는 값만 배열로 리턴
// user.id가 일치하지 않는 원소만 추출하여 새로운 배열로 리턴
setUsers(users.filter(user => user.id !== id));
}
const onToggle = (id) => {
// map : 배열의 처리를 하여 배열로 리턴
// forEach : 배열의 처리만 하고 리턴하지 않음
// user.id가 파라미터의 id와 일치하면 active의 상태를 반전시켜 줌.
setUsers(users.map(u=>
u.id === id ? { ...u, active: !u.active} : u
))
}
return (
<div className='userList'>
{/* 컴포넌트에서 데이터를 하위 컴포넌트에게 전달하는 방법 = props */}
{/* {
users.map(u=>(
<User user={u} key={u.id}/>
))
} */}
<CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/>
{
users.map((u)=>(
<User user={u} key={u.id} onRemove={onRemove} onToggle={onToggle}/>
))
}
</div>
);
};
export default UserList;
※ == 와 === 의 차이점
: `===`는 엄격한 동등 비교로, 타입과 값이 모두 같아야 참(true)입니다. `==`는 느슨한 동등 비교로, 타입이 다르면 자동으로 변환 후 비교합니다.
▷ 출력
2. 느낀 점
오늘 수업을 들으면서 수업 내용을 거의 이해할 수 있어서 기뻤다. 오늘 배운 내용을 까먹지 않도록 주말에 복습을 해야겠다.
'Front-end > React' 카테고리의 다른 글
React 기초(db 연동)- AWS 풀스택 과정 42일차 (0) | 2024.09.19 |
---|---|
React 기초(useReducer)- AWS 풀스택 과정 41일차 (0) | 2024.09.10 |
React 기초(todoList)- AWS 풀스택 과정 40일차 (0) | 2024.09.09 |
React 기초(input, param)- AWS 풀스택 과정 38일차 (0) | 2024.09.05 |
React 설정 및 기초- AWS 풀스택 과정 37일차 (4) | 2024.09.04 |