state를 활용한 컴포넌트 사이의 데이터 전달
기존에는 부모 컴포넌트에서 props를 통해 자식 컴포넌트는 데이터를 읽어올 수 있고,
자식 컴포넌트에서 해당 변수를 변경하더라도 부모 컴포넌트에는 영향을 미치지 않았는데 state를 활용하면 이가 가능하다
이를 가능하게 하기 위해서는 자식 컴포넌트가 부모 컴포넌트에게서 변수와 해당 변수를 변경할 수 있는 set 함수를
함께 받아오면 되는 것인데, 예시를 통해 더 자세히 알아보고자 한다
[한 컴포넌트 안에서 모든 동작이 이루어지는 경우]
import {useState} from 'react';
function UserList(){
const[user, setUser] = useState({name:'', age:'', address:'', tel:''});
const [userList, setUserList] = useState([]);
const change = (e) => {
let name = e.target.name;
let value = e.target.value;
setUser({...user, [name] : value});
}
const addUser = () =>{
setUserList([...userList, user]);
setUser({name:'', age:'', address:'', tel:''});
}
return (
<div className="App">
이름 : <input type="text" name="name" value={user.name} onChange={change} /><br/>
나이 : <input type="text" name="age" value={user.age} onChange={change}/><br/>
주소 : <input type="text" name="address" value={user.address} onChange={change}/><br/>
전화 : <input type="text" name="tel" value={user.tel} onChange={change}/><br/><br/>
<button onClick={addUser}>추가</button><br/><br/>
// (1)
{userList.length>0 && <table border="1">
<tbody>
<tr><th>이름</th><th>나이</th><th>주소</th><th>전화번호</th></tr>
{userList.map((item) =>
(
<tr key={item.name}>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.address}</td>
<td>{item.tel}</td>
</tr>
)
)}
</tbody>
</table>}
</div>
);
}
export default UserList;
(1) 특정 조건을 만족했을 때 태그를 보이게 하고 싶은 경우 사용하는 것으로, 조건을 만족했을 때 변경할 태그를 중괄호로 감싼 후 { (조건절) && (태그)} 의 형태를 이루면, 왼쪽 조건절이 T일 경우 왼쪽의 태그가 출력됨
위의 컴포넌트는 한 컴포넌트 내에서 이름/나이/주소/전화번호를 입력한 후 버튼을 클릭하면 아래 리스트에 적용되는 형태인데,
입력하는 것을 자식 컴포넌트(UserAdd) / 리스트로 출력되는 것을 부모 컴포넌트(UserTable)로 컴포넌트를 분리해 볼 것이다
컴포넌트를 분리할 경우 부모 컴포넌트가 자식 컴포넌트에서 입력한 데이터를 가지고 와야 하는데,
이 때 사용하는 것이 state이다.
[부모 컴포넌트 UserTable.js]
import {useState} from 'react';
import UserAdd from './UserAdd';
function UserTable(){
const [userList, setUserList] = useState([]);
return (
<div className="App">
{/* (1) */}
<UserAdd userList={userList} setUserList={setUserList}/>
{userList.length>0 && <table border="1">
<tbody>
<tr><th>이름</th><th>나이</th><th>주소</th><th>전화번호</th></tr>
{userList.map((item) =>
(
<tr key={item.name}>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.address}</td>
<td>{item.tel}</td>
</tr>
)
)}
</tbody>
</table>}
</div>
);
}
export default UserTable;
- 전체 코드와 다른점은 거의 없고 (1)과 같이 부모 컴포넌트에 자식 컴포넌트를 가지고 왔다는 차이가 존재
(1) 자식 컴포넌트를 출력
: 자식 컴포넌트에서 입력한 값을 이용해 아래 리스트에 출력해 줘야 하기 때문에 변경되어야 하는 userList와 이를 변경하는 set함수인 userList를 자식 컴포넌트에게 넘겨줌
[자식 컴포넌트 UserAdd.js]
import {useState} from 'react';
function UserAdd({userList, setUserList}){ // (1)
const[user, setUser] = useState({name:'', age:'', address:'', tel:''});
const change = (e) => {
let name = e.target.name;
let value = e.target.value;
setUser({...user, [name] : value});
}
const addUser = () =>{
setUserList([...userList, user]);
setUser({name:'', age:'', address:'', tel:''});
}
return(
<>
이름 : <input type="text" name="name" value={user.name} onChange={change} /><br/>
나이 : <input type="text" name="age" value={user.age} onChange={change}/><br/>
주소 : <input type="text" name="address" value={user.address} onChange={change}/><br/>
전화 : <input type="text" name="tel" value={user.tel} onChange={change}/><br/><br/>
<button onClick={addUser}>추가</button><br/><br/>
</>
)
}
export default UserAdd;
(1) 부모 컴포넌트로부터 받은 userList와 set 함수를 가져옴
- 이를 이용해 추가 버튼을 클릭하면 해당 userList에 user가 추가되도록 로직을 작성
하나의 컴포넌트를 2개의 컴포넌트로 나누는 것
부모의 컴포넌트에 있는 데이터를 자식 컴포넌트에서 변경하는 것
어려워 보이기는 하지만 실상 이해하면 많이 어렵지 않은 로직임을 알 수 있다:)
'공부 자료 > 리액트[React]' 카테고리의 다른 글
[React] 버튼 기능 / Badge, ButtonStrap, ButtonGroupStrap (0) | 2023.10.26 |
---|---|
[React] Bootstrap/Reactstrap 설치 (0) | 2023.10.26 |
[React] State 사용하기 (0) | 2023.10.26 |
[React] PropsRequired로 required 옵션 실현 (0) | 2023.10.25 |
[React] PropsDataType/자료형 타입 확인 (1) | 2023.10.25 |