
인풋 요소에 발생하는 변경사항을 수신만 하는것이 아니라 인풋 요소에 새 값을 넣을 수 있다.
정리하면
1. 인풋요소에 들여오는 데이터를 저장하거나 사용한다.
2. useState를 사용하여 데이터값 초기화.
3. value 속성을 이용하여 초기화값 가져오기.
마치 무한루프처럼 보이지만 전혀 문제가 없다.
const submitHandler = (event) => {
event.preventDefault();
const peopleData = {
age: enteredAge,
weight: enteredWeight,
home: enteredHome,
};
console.log(peopleData);
// 인풋값 초기화하기.
setEnteredAge("0");
setEnteredWeight("0");
setEnteredHome("초기화");
};
return(
...
<input
type="text"
value={enteredAge} // value 태그를 이용하여 인풋값 초기화 행위를 가져오자.
onChange={ageChangeHandler}
></input>
...
);
입력 양식에 따라 입력을 해준뒤..
제출을 누르게되면 위 사진처럼 input 요소에 값이 초기화가 된다.
이와같은 양방향 바인딩은 리액트에서 중요한 개념이므로 잘 숙지해야한다.
부모 컴포넌트가 자식 컴포넌트에게 특정 데이터를 넘겨주고자 하면 props를 사용해서 간단하게 넘겨주었다.
하지만 자식 컴포넌트가 부모 컴포넌트에게 데이터를 넘겨주고자 하면 다른방식을 사용해야한다.
함수를 사용하여 부모 컴포넌트에게 데이터를 전달하자!
다음은 사용 예시.
NewPeople.js는 부모 컴포넌트
NewPeopleForm.js는 자식 컴포넌트
NewPeople.js
const NewPeople = () => {
// 1. 함수선언을 부모 컴포넌트에 선언한다.
const savePeopleDataHandler = (enteredPeopleData) => {
const peopleData = {
...enteredPeopleData
}
console.log("부모 컴포넌트가 자식컴포넌트에게 데이터를 받기");
console.log(peopleData);
}
return (
<div className="new-people">
// 2. 함수를 자식 컴포넌트에게 프로퍼티로 전달한다.
<NewPeopleForm onSavePeopleData ={ savePeopleDataHandler }/>
</div>
);
};
NewPeopleForm.js
const NewPeopleForm = (props) => {
const peopleData = {
age: enteredAge,
weight: enteredWeight,
home: enteredHome,
};
// 3.자식 컴포넌트에서 부모 컴포넌트에게 받은 함수를 사용하여 데이터를 넘긴다. (파라미터 전달)
props.onSavePeopleData(peopleData);
return (
...
);
}
자식 컴포넌트에게 데이터를받아서 부모 컴포넌트가 데이터를 출력할 수 있게 되었다!
손그림으로 데이터 흐름을 정리해보자.
위 사진처럼 선택 년도를 제외한 년도를 표시하도록 코드를 작성하려고한다.
배운것으로 해본다면 상태를 하나 더 사용하여 관리하고자 생각 했을 것이다.
People.js
const People = (props) => {
const [filterdYear , setFilteredYear ] = useState('2020');
// 상태를 하나 더 사용하여 관리하기
const [filterInfoText, setFilterInfoText ] = useState('2019, 2021 &2022')
const filterChangeHandler = (selctedYear) => {
setFilteredYear(selctedYear);
if (selctedYear === "2019") {
setFilterInfoText('2020,2021 &2022')
} else if (selctedYear === "2020") {
setFilterInfoText('2019,2021 &2022')
} else if (selctedYear === "2021") {
setFilterInfoText('2019,2020 &2022')
} else if (selctedYear === "2022") {
setFilterInfoText('2019,2020 &2021')
}
}
return (
<div>
<p> {filterInfoText} </p>
<div>
}
이런 방식이 틀리다는것은 아니지만 최선은 아니다. 왜냐하면 상태를 사용하여 받아오는 값의 성질이 비슷하기 때문이다.
const [filterdYear , setFilteredYear ] = useState('2020');
const [filterInfoText, setFilterInfoText ] = useState('2019, 2021 &2022')
두 상태가 받아오는 source를 보면..
‘2020’
‘2019,2021 & 2022’
source가 비슷한것을 볼 수 있다.
따라서 불필요한 상태 업데이트를 줄이고자 해보자.
const People = (props) => {
const [filterdYear , setFilteredYear ] = useState('2020');
// 상태를 사용하는대신 변수를 사용해 관리하자.
// 이 코드들은 상태가 업데이트 될때마다 마찬가지로 런타임 실행이 된다.
let filterInfoText = '2019, 2021 &2022';
if (filterdYear === "2019") {
filterInfoText = ('2020,2021 &2022')
} else if (filterdYear === "2021") {
filterInfoText = ('2019,2020 &2022')
} else if (filterdYear === "2022") {
filterInfoText = ('2019,2020 &2021')
}
const filterChangeHandler = (selctedYear) => {
setFilteredYear(selctedYear);
}
return (
<div>
<p> {filterInfoText} </p>
<div>
}
계산된 값 ( 파생된 값 ) : 상태에 의존하여 값이 결정된다.
제어 컴포넌트 : React에 의해서 값이 제어되는 컴포넌트
비 제어 컴포넌트 : React에 의해서 값이 제어되지 않는 컴포넌트
=> ( 강의에서는 자세한 내용이 나오지않고, 구글링해보니 ref관련 개념이나오는것으로 보아 추후 배울 내용인것 같다. )
제어 컴포넌트의 예시로 아래 코드의 예시는
“NewPeople(부모) 컴포넌트는 NewPeopleForm(자식) 컴포넌트를 제어한다“고
표현할 수 있다.
NewPeopleForm 컴포넌트는 로직을 처리하지 않는다.
PeopleData를 GUI에 표현하거나 그럴수 있어도 실제 로직을 처리하는것은
NewPeople 컴포넌트에서 처리한다는 것이다.
이럴경우 NewPeople 컴포넌트는 NewPeopleForm 컴포넌트를 제어한다고 표현한다.
NewPeople.js
const NewPeople = (props) => {
const savePeopleDataHandler = (enteredPeopleData) => {
const peopleData = {
...enteredPeopleData
}
console.log("부모 컴포넌트가 자식컴포넌트에게 데이터를 받기");
console.log(peopleData);
props.onAddPeopleData(peopleData);
}
return (
<div className="new-people">
<NewPeopleForm onSavePeopleData ={ savePeopleDataHandler }/>
</div>
);
};
NewPeopleForm.js
props.onSavePeopleData(peopleData);
상태 저장(stateful) 컴포넌트 vs 상태 비저장(statless) 컴포넌트
개수 차이만 보면 상태 비저장 컴포넌트가 더 많다.
몇개의 컴포넌트만이 상태를 관리하기 때문이다.
상태 저장(stateful) 컴포넌트 : 상태를 관리하는 컴포넌트를 상태 저장 컴포넌트라 한다.
People.js
// filter 상태를 관리하는 상태 저장 컴포넌트
const [filterdYear , setFilteredYear ] = useState('2020');
NewPeopleForm.js
// input 상태를 관리하는 상태 저장 컴포넌트
const [enteredAge, setEnteredAge] = useState("");
const [enteredWeight, setEnteredWeight] = useState("");
const [enteredHome, setEnteredHome] = useState("");
상태 저장 컴포넌트의 자주 보는 패턴 예시
People 컴포넌트에서 filterdYear 상태를 프로퍼티를 이용하여 PeopleFilter에게 전달한다. 이 패턴이 가장 흔하게 볼 수 있는 패턴이다.
People.js
const People = (props) => {
...
const [filterdYear , setFilteredYear ] = useState('2020');
...
return (
...
<PeopleFilter selected={filterdYear} onChangeFilter = {filterChangeHandler} />
...
)
}