https://react.vlpt.us/basic/09-multiple-inputs.html 참고
배열 렌더링 때에는 key가 존재해야 한다. 중복되는 key 가 있으면 오류메세지가 생기며 업데이트가 안됨
import React from 'react'
function User({ user }) {
return (
<div>
<b>{user.username}</b> <span>({user.email})</span>
</div>
)
}
function UserList() {
const users =[
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com'
},
{
id: 2,
username: 'tester',
email: 'tester@gmail.com'
},
{
id: 3,
username: 'liza',
email: 'liz@gmail.com'
},
]
return (
<div>
{users.map((user, index)=> (
<User user={user} key={index}/>
))}
</div>
);
}
export default UserList
또는 배열 내에 존재하는 값으로 key 값 설정하기
import React from 'react'
function User({ user }) {
...
}
function UserList() {
...
return (
<div>
{users.map(user=> (
<User user={user} key={user.id}/>
))}
</div>
);
}
export default UserList
DOM을 직접 선택하여 가져와야할 때
ex 특정 element의 크기를 가져오거나, 스크롤바 위치를 가져오거나, 설정하거나, 포커스를 설정하거나...
→ ref 를 이용한다
함수형 component에서 ref를 사용할 때에는 useRef
라는 Hook 함수를 사용한다.
초기화를 눌렀을 때 이름 input에 포커스가 잡히도록
import React, {useState, useRef} from 'react';
function InputSample() {
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
})
}
const onReset = (e) => {
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}/>
<div>
<b>값: </b>
{name}({nickname})
</div>
<button onClick={onReset}>초기화</button>
</div>
)
}
export default InputSample;
useRef
로 Ref객체를 만들고, 이 객체를 원하는 DOM에 ref
값으로 설정
→ Ref 객체의 .current
값은 원하는 DOM을 가리키게 됨
useRef
를 DOM 을 선택하는 것 이외에도, component 내에서 조회 및 수정할 수 있는 변수를 관리하는 용도로 쓸 수도 있다.
다음과 같은 값을 관리할 수 있다
setTimeout
, setInterval
을 통해 만들어진 iduseRef() 에 넣어준 parameter 값이 .current
값의 기본 값이 된다.
수정 또는 조회시에도 .current
를 이용
- App.js
import './App.css';
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@gmail.com'
},
{
id: 3,
username: 'liza',
email: 'liz@gmail.com'
},
]);
const nextId = useRef(4);
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
};
setUsers([...users, user]);
setInputs({
username: '',
email: ''
})
nextId.current += 1;
}
return (
<div className="App">
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
< UserList users = {users}/>
</div>
);
}
export default App;
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;
* 배열의 push, splice 등의 함수를 사용하면 안된다.
대신 spread, concat 이용
ex : users.concat(user)
onToggle, onRemove 등 함수 추가한 최종본
App.js
import './App.css';
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',
active : true,
},
{
id: 2,
username: 'tester',
email: 'tester@gmail.com',
active : false,
},
{
id: 3,
username: 'liza',
email: 'liz@gmail.com',
active : false,
},
]);
const nextId = useRef(4);
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
};
setUsers([...users, user]);
setInputs({
username: '',
email: ''
})
nextId.current += 1;
}
const onRemove = id => {
setUsers(users.filter(users => users.id !== id));
};
const onToggle = id => {
setUsers(
users.map(user => user.id === id ? { ...user, active : ! user.active } : user)
)
}
return (
<div className="App">
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
< UserList users = {users} onRemove={onRemove} onToggle={onToggle}/>
</div>
);
}
export default App;
import React from 'react'
function User({ user, onRemove, onToggle }) {
return (
<div>
<b
style={{
cursor: 'pointer',
color: user.active? 'green' : 'black'
}}
onClick={()=> onToggle(user.id)}
>
{user.username}
</b>
<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