<< 학습 목표 >>
1. 컴포넌트 간 데이터를 주고 받기 위해 useContext 훅을 사용할 수 있다.
전 글 ( https://codingaja.tistory.com/84 ) 에서 컴포넌트간에 데이터를 주고 받기 위해 사용한 방식을 useContext 훅을 사용한 방식으로 바꿔보자
글의 제목은 개선이라고 썼지만 프로젝트의 컴포넌트 트리가 간단하므로 개선이라기 보단 바꾼다 가 더 적합함
우선 코드를 모두 입력하고 설명을 보자
<< AddressMng 컴포넌트 >>
import React, {useState} from 'react';
import AddressAdd from './AddressAdd';
import AddressList from './AddressList';
export const AddressContext = React.createContext();
function AddressMng() {
const [address, setAddress] = useState();
return(
<div className="container">
<div className="text-center">
<h1>[ 주소록 관리 프로젝트 (useContext) ]</h1>
<hr />
</div>
<AddressContext.Provider value={ {address, setAddress} }>
<AddressAdd />
<AddressList/>
</AddressContext.Provider>
</div>
);
}
export default AddressMng;
<< AddressAdd 컴포넌트 >>
import React, {useRef, useContext} from 'react';
import { AddressContext } from './AddressMng';
function AddressAdd() {
let nameRef = useRef(null);
let telRef = useRef(null);
let addressRef = useRef(null);
const setAddress = useContext(AddressContext).setAddress;
let clickAddBtn = () => {
let address = {
"name": nameRef.current.value,
"tel": telRef.current.value,
"address": addressRef.current.value
}
setAddress(address);
}
return(
<div id="add_panel">
<div className="row align-items-center justify-content-center">
<div className="col-2">
<input type="text" className="form-control" placeholder="이름" ref={nameRef} />
</div>
<div className="col-2">
<input type="tel" className="form-control" placeholder="연락처" ref={telRef} />
</div>
<div className="col-5">
<input type="text" className="form-control" placeholder="주소" ref={addressRef} />
</div>
<div className="col-2 text-center">
<button type="button" className="btn btn-primary" onClick={clickAddBtn}>추가</button>
</div>
</div>
<hr />
</div>
);
}
export default AddressAdd;
<< AddressList 컴포넌트 >>
import React, {useState, useEffect, useContext} from 'react';
import Address from './Address';
import { AddressContext } from './AddressMng';
function AddressList() {
const [addressList, setAddressList] = useState([]);
const address = useContext(AddressContext).address;
useEffect(() => {
if(address != null) {
let newAddressList = Array.from(addressList);
newAddressList.push(address);
setAddressList(newAddressList);
}
}, [address]);
return(
<div id="list_panel">
<table className="table text-center">
<thead>
<tr className="row">
<th className="col-1" scope="col"></th>
<th className="col-2" scope="col">이름</th>
<th className="col-2" scope="col">연락처</th>
<th className="col-5" scope="col">주소</th>
<th className="col-2" scope="col"></th>
</tr>
</thead>
<tbody>
{
addressList.map((address, index) => {
return <Address key={index} number={address.number} name={address.name} tel={address.tel} address={address.address} />
})
}
</tbody>
</table>
</div>
);
}
export default AddressList
<< AddressMng 컴포넌트와 AddressAdd 컴포넌트 설명 >>

(1). 부모 컴포넌트와 자식 컴포넌트들이 공유해서 사용할 Context(공용 변수) 생성
(2). 자식 컴포넌트에서 전달할 값을 받기 위한 변수 선언
(3). 자식 컴포넌트들이 Context를 사용할 수 있도록 설정
(4). 전 글 ( https://codingaja.tistory.com/85 ) 에서는 자식 컴포넌트로 간단하게 "Hi" 문자열을 전달했지만 이번에는 address와 setAddress 를 전달
address는 주소 정보를 저장할 값이지만 setAddress는 setter 함수라는 점에 유의하자
JS는 함수가 1급 객체이기 때문에 이와 같이 함수를 전달할 수도 있음
자식 컴포넌트로 값들을 보내기 위해 { } 로 묶었다는 점에도 유의하자
address는 AddressList 컴포넌트에서 사용하고 setAddress는 AddressAdd 컴포넌트에서 사용함
(5). AddressMng 부모 컴포넌트가 전달한 setter 를 꺼내기 위해 공용 변수를 import함
(6). 공용 변수에 들어있는 setter를 꺼내기 위해 우선 useContext 훅을 사용함
conset setAddress = useContext(AddressContext); 만 하게 되면 setAddress 변수에 address 값을 갖고 있는 변수와 setter 함수가 모두 저장됨, 이와 같이 했다면 setAddress.setAddress(address); 로 해야하기에 좀 더 편하게 사용하기 위해 공용 변수가 갖고 있는 setter 함수만 setAddressd 변수에 저장함
(7). 부모 컴포넌트가 공용 변수에 담아서 보내준 setter 를 사용해서 주소 정보 저장
<< AddressList 컴포넌트 설명 >>

(1). AddressMng 부모 컴포넌트가 전달한 공용 변수를 사용하기 위해 import함
(2). 공용 변수 내 address 변수의 값(주소 정보)만 꺼냄
(3). 꺼낸 주소 정보를 주소록에 저장
바뀐 부분이 크게 없다고 느끼거나 "왜 굳이 useContext 를 사용하지?" 라고 느낄 수 있음
이 글의 처음에 언급했듯 우리 프로젝트의 규모가 작아서 그런것이므로 여기서 알려준 방법대로 부모 컴포넌트와 자식 컴포넌트가 값을 주고 받는 방법을 잘 기억해두면 포트폴리오 또는 현업에서 도움이 많이 될 것
'JS + React > React-Chapter03' 카테고리의 다른 글
| Chapter03. 리엑트 프로젝트 / 주소록 수정, 삭제 (0) | 2023.04.03 |
|---|---|
| Chapter03. 리엑트 / 컨텍스트(Context), useContext 훅 (0) | 2023.04.01 |
| Chapter03. 리엑트 프로젝트 / 주소록 추가, 출력 (0) | 2023.04.01 |
| Chapter03. 리엑트 프로젝트 / 주소록 관리 (0) | 2023.04.01 |
| Chapter03. 리엑트 훅 / useRef 훅 (0) | 2023.04.01 |