-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
210413 | update learn react document contents
- Loading branch information
1 parent
8e1db96
commit e8f2ffa
Showing
25 changed files
with
1,250 additions
and
6 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
08_react/04_learn-document/01_main_concept/10_lifting_state.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// state 끌어올리기 | ||
// 두 입력값이 서로의 것과 동기화된 상태로 만들기 | ||
// ex) 섭씨 <=> 화씨 자유롭게 변환 가능 | ||
|
||
const scaleNames = { | ||
c: 'Celsius', | ||
f: 'Fahrenheit' | ||
}; | ||
|
||
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 BoilingVerdict({ celsius }) { | ||
return <p>The water would {celsius >= 100 && 'not'} boil.</p>; | ||
} | ||
|
||
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); | ||
// 부모 컴포넌트 쪽에 공유될 state를 소유 => 두 자식 컴포넌트의 입력 필드에 대한 진리의 원천(source of truth)이 된다. | ||
// 두 입력 필드가 서로 간에 일관된 값을 유지하도록 만들 수 있다. | ||
// 입력 필드들로부터 "끌어올린" state | ||
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.getElementById('root') | ||
); |
64 changes: 64 additions & 0 deletions
64
08_react/04_learn-document/01_main_concept/11_composition_inheritance.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// React는 강력한 합성 모델을 가지고 있으며, 상속 대신 합성을 사용하여 컴포넌트 간에 코드를 재사용 하는 것이 좋다. | ||
function FancyBorder(props) { | ||
console.log(props); | ||
// <FancyBorder> JSX 태그 안에 있는 것들이 FancyBorder 컴포넌트의 children prop으로 전달된다. | ||
// FancyBorder는 {props.children}을 <div> 안에 렌더링하므로 전달된 엘리먼트들이 최종 출력된다. | ||
return ( | ||
<div className={'FancyBorder FancyBorder-' + props.color}> | ||
{props.children} | ||
</div> | ||
); | ||
} | ||
|
||
function Dialog(props) { | ||
console.log(props); | ||
return ( | ||
<FancyBorder color="blue"> | ||
<h1 className="Dialog-title"> | ||
{props.title} | ||
</h1> | ||
<p className="Dialog-message"> | ||
{props.message} | ||
</p> | ||
</FancyBorder> | ||
); | ||
} | ||
|
||
// function WelcomeDialog() { | ||
// return ( | ||
// <FancyBorder color="blue"> | ||
// <h1 className="Dialog-title"> | ||
// Welcome | ||
// </h1> | ||
// <p className="Dialog-message"> | ||
// Thank you for visiting our spacecraft! | ||
// </p> | ||
// </FancyBorder> | ||
// ); | ||
// } | ||
|
||
function WelcomeDialog() { | ||
return ( | ||
<Dialog | ||
title="Welcome" | ||
message="Thank you for visiting our spacecraft!" /> | ||
); | ||
} | ||
|
||
ReactDOM.render( | ||
<WelcomeDialog />, | ||
document.getElementById('root') | ||
); | ||
|
||
|
||
// 상속(Inheritance): is-a | ||
// - 다른 부모클래스를 만든 후 자식클래스는 이 부모클래스를 상속받아서 구현을 정의 | ||
|
||
// 합성(Composition): has-a | ||
// - 서로 다른 객체를 여러 개 붙여서 새로운 기능이나 객체를 구성 | ||
// - 일반적으로 합성 할 클래스를 변수에 할당 후 사용하는 구조 | ||
// - 이렇게 합성한 경우 상속과는 다르게 클래스간의 유기적으로 서로의 클래스를 융통성있게 합성할 수 있음 | ||
|
||
// 결론 | ||
// - 상속은 재사용의 관점보다는 기능 확장에 사용합니다. | ||
// - 재사용을 하기 위해서는 합성(Composition) has-a 방식을 사용합시다. |
65 changes: 65 additions & 0 deletions
65
08_react/04_learn-document/01_main_concept/11_composition_inheritance_class.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// 요약하면 React에서는 컴포넌트를 재사용해서 구성하는 것이 좋다. | ||
// props와 합성은 명시적이고 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징하는데 필요한 모든 유연성을 제공한다. | ||
// 컴포넌트가 원시 타입의 값, React 엘리먼트 혹은 함수 등 어떠한 props도 받을 수 있다. | ||
function FancyBorder(props) { | ||
console.log(props); | ||
return ( | ||
<div className={'FancyBorder FancyBorder-' + props.color}> | ||
{props.children} | ||
</div> | ||
); | ||
} | ||
|
||
function Dialog(props) { | ||
console.log(props); | ||
return ( | ||
<FancyBorder color="blue"> | ||
<h1 className="Dialog-title"> | ||
{props.title} | ||
</h1> | ||
<p className="Dialog-message"> | ||
{props.message} | ||
</p> | ||
{props.children} | ||
</FancyBorder> | ||
); | ||
} | ||
|
||
class SignUpDialog extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
console.log(props); | ||
this.handleChange = this.handleChange.bind(this); | ||
this.handleSignUp = this.handleSignUp.bind(this); | ||
this.state = {login: ''}; | ||
} | ||
|
||
render() { | ||
return ( | ||
<Dialog | ||
title="Mars Exploration Program" | ||
message="How should we refer to you?"> | ||
<input | ||
value={this.state.login} | ||
onChange={this.handleChange} | ||
/> | ||
<button onClick={this.handleSignUp}> | ||
Sign Me Up! | ||
</button> | ||
</Dialog> | ||
); | ||
} | ||
|
||
handleChange(e) { | ||
this.setState({login: e.target.value}); | ||
} | ||
|
||
handleSignUp() { | ||
alert(`Welcome aboard, ${this.state.login}!`); | ||
} | ||
} | ||
|
||
ReactDOM.render( | ||
<SignUpDialog />, | ||
document.getElementById('root') | ||
); |
Oops, something went wrong.