끌어올리기
두개 이상의 컴포넌트에서 같은 데이터를 사용하고 변경사항을 동시에 렌더링해야할 경우가 있다
그럴 때는 두개의 컴포넌트에서 가장 가까운 공통 조상까지 데이터를 끌어올린 뒤에 조작과 출력을 제어한다
아래의 코드는 리액트 공식 홈페이지의 튜토리얼에서 가져온 코드이다
import React from 'react';
import ReactDOM from 'react-dom';
const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};
function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
}
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 toCelsius(fahrenheit) {
return (fahrenheit - 32) * 5 / 9;
}
function toFahrenheit(celsius) {
return (celsius * 9 / 5) + 32;
}
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onTemperatureChange(e.target.value);
}
render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '', scale: 'c'};
}
handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
}
handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
}
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
}
ReactDOM.render(
<Calculator/>,
document.querySelector('#root')
);
간단하게 설명하면 화씨와 섭씨를 입력받는 input이 두개있고
화씨의 값을 바꾸면 섭씨의 input 값이,
섭씨의 값을 바꾸면 화씨의 input 값이 서로 변환되어 반영된다
여기서 주의할 점은 TemperatureInput컴포넌트 temperature값은 Calculator의 state라는 것
이 state의 값을 업데이트하기 위해 TemperatureInput컴포넌트에서 불러오는 이벤트 함수 handleChange또한
handleChange(e) {
this.props.onTemperatureChange(e.target.value);
}
handleChange함수가 직접 바꾸는게 아닌 Calculator에서 넘겨준 함수
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} /> <=========
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} /> <=========
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
들을 호출해서
handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
}
handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
}
Calculator 내부의 state를 바꾼다는 것
그렇게 바뀐 state를 두개의 input컴포넌트에서 공유하고 있기 때문에 하나의 값을 수정하면 다른 하나도 동시에 바뀌게되는 것이다
'React' 카테고리의 다른 글
State Hook (0) | 2020.11.17 |
---|---|
composition (0) | 2020.11.15 |
controlled component (0) | 2020.11.13 |
list, key (0) | 2020.11.06 |
조건부 렌더링 (0) | 2020.11.05 |