Shared State
Shared State : State에 있는 데이터를 여러개의 하위 컴포넌트에서 공통적으로 사용하는 경우, 하위 컴포넌트가 공통된 부모 컴포넌트의 state를 공유하여 사용하는 것, 하위 컴포넌트의 state를 공통 상위 컴포넌트로 올림
하위컴포넌트에서 State 공유하기
//물의 끓음 여부를 알려주는 컴포넌트
function BilingVerdic(props){
if(props.celsius >= 100) {
return <p>물이 끓습니다.</p>;
}
return <p>물이 끓지 않습니다.</p>;
}
//
function Calculator(props){
const [temperature, setTemperature] = useState('');
const handleChange = (event) => {
setTemperature(event.target.value);
}
return(
<fieldset>
<legend>섭씨 온도를 입력하세요.</legend>
<input
value={temperature}
onChange={handleChange}>
<BoilingVerdict
celsius={parseFloat(temperature)}>
</fieldset>
)
}
//State 공유하기
function Calculator(props){
return(
<div>
<TemperatureInput scale="c">
<TemperatureInput scale="f">
</div>
);
}
//입력 컴포넌트 추출하기 : 구분하여 입력받기위함, 재사용가능
const scaleNames = {
c: '섭씨',
f: '화씨'
}
function TemperatureInput(props){
const [temperature, setTemperature] = useState('');
const handleChange = (event) => {
//lifting state
//setTemperature(event.target.value);
props.onTemperatureChange(event.target.value);
}
return(
<fieldset>
<legend>온도를 입력해줏요(단위:{scaleNames[props.scale]});</legend>
//lifting state
//<input value={temperature} onChange={handleChange}>
<input value={props.temperature} onChange={handleChange}>
</fieldset>
)
}
//온도변환함수 작성하기
function toCelsius(fahrenheit){
return (fahrenheit - 32) *5 /9;
}
function toFahrenheit(celsius){
return (celsius *9 /5) + 32;
}
//값변환
//tryConvert('abc', toCelsius); empty string리턴
//tryConvert('10.22', toFahrenheit); '50.396'리턴
function tryConvert(temperature, convert){
const input = parseFloat(temperature);
if(Number.isNaN(input)){
return '';
}
const output = convert(input);
const rounded = Math.round(output *1000) /1000;
return rounded.toString();
}
//최종
function Calculator(props){
const [temperature, setTemperature] = useState('');
const [sacle, setScale] = useState('c');
const handleCelsiusChange = (temperature) => {
setTemperature(temperature);
setScale('c');
}
const handleFahrenheitChange = (temperature) => {
setTemperature(temperature);
setScale('f');
}
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return(
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={handleCelsiusChange}>
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={handleFahrenheitChange}>
<BoilingVerdict
celsius={parseFloat(celsius)}>
</div>
)
}
(실습) 섭씨온도와 화씨온도 표시하기
//TemperatureInput.jsx
const scaleNames = {
c: "섭씨",
f: "화씨",
};
function TemperatureInput(props){
const handleChange =(event) => {
props.onTemperatureChange(event.target.value);
};
return(
<fieldset>
<legend>
온도를 입력해주세요(단위:{scaleNames[props.scale]});
</legend>
<input value={props.temperature} onChange={handleChange}/>
</fieldset>
);
}
export default TemperatureInput;
//calculator.jsx
import React, {useState} from "react";
import TemperatureInput from "./TemperatureInput";
function BoilingVerdict(props){
if(props.celsius >= 100) {
return <p>물이 끓습니다.</p>;
}
return <p>물이 끓지않습니다.</p>;
}
function toCelsius(fahrenheit) {
return ((fahrenheit - 32) * 5) / 9;
}
function toFahrenheit(celsius) {
return (celsius * 9) / 5 + 32;
}
function tryConvert(temperature, convert) {
const input = parseFloat(temperature);
if(Number.isNaN(input)){
return "";
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();
}
function Calculator(props) {
const [temperature, setTemperature] = useState("");
const [scale, setScale] = useState("c");
const handleCelsiusChange = (temperature => {
setTemperature(temperature);
setScale("c");
});
const handleFahrenheitChange = (temperature) => {
setTemperature(temperature);
setScale("f");
};
const celsius = scale === "f" ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature;
return(
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={handleCelsiusChange}
/>
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={handleFahrenheitChange}
/>
<BoilingVerdict celsius={parseFloat(celsius)} />
</div>
)
}
export default Calculator;
반응형
'REACT > [inflearn] 처음만난 리액트' 카테고리의 다른 글
14강. Context (0) | 2022.12.02 |
---|---|
13강. Composition vs Inheritance (0) | 2022.11.30 |
11강. Forms (0) | 2022.11.21 |
10강. List and Keys (0) | 2022.11.11 |
9강. Conditional Rendering (0) | 2022.11.10 |