데이터가 바뀌면 화면(을 구성하는 컴포넌트)을 재랜더링 함
이를위해 리액트에는 Props와 State를 사용하여 변경되는 데이터를 체크한다.
Props와 State는 비슷하지만 활용목적에 있어 차이가 있다.
state는 컴포넌트에 데이터 저장
props는 컴포넌트간 데이터를 전달
<script type="text/babel">
class C extends React.Component {
render(){
const { text } = this.props
return(
<span>Hello World { text }</span>
)
}
}
class B extends React.Component {
render(){
const { value } = this.props //js영역
return( //jsx영역
<div className="c_Component">
<C text={value} />
</div>
)
}
}
class A extends React.Component {
render(){
const { name } = this.props
return(
<div>
<B value={name}/>
</div>
)
}
}
class App extends React.Component {
render(){
return(
<div>
<A name={"heidi"} />
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
자식 컴포넌트는 value를 통해 부모 컴포넌트에 값을 넘길 수 있음
여기서의 value는 input 속성의 value를 의미하는 것이 아닌, 리액트에서 전달하는 props속성의 이름을 말한다.
ㄴ부모 컴포넌트의 value는 html
ㄴ자식 컴포넌트의 value는 속성 값
부모 컴포넌트에 constructor(props){supet(props)} 를 주면 자식 컴포넌트의 속성 값을 가져올 수 있다.
(최근에는 생략 가능해졌다)
브라우저에서는 class로 인식하기 때문이다.
넘기는 속성값의 이름은 value가 아닌 다른 것으로도 전달이 가능하다.
render 부분의 js영역의 {}객체와 return의 jsx영역의 {}변수 기호를 구분하는 것이 중요하다.
<script type="text/babel">
class Login extends React.Component {
// constructor(props){
// super(props)
// this.state = {}
// }
state = {
isLogin : false
}
// setState({
// ...state,
// name : 'heidi2'
// })
render(){
const obj = {
...this.stste,
isLogin : !this.state.isLogin
}
return(
<button onClick={ () => {this.setState(obj)} }>
{this.state.isLogin ? '로그아웃' : '로그인' }
</button>
)
}
}
class App extends React.Component {
render(){
return(
<div>
<Login />
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
render()는 컴포넌트가 실행되었을 때 실행되는 함수다. 랜더함수 안에 함수를 넣어두면 계속 실행되기 때문에 state는 가급적 constructor 안에 넣어둔다.
{} === {} //false
state.name = 'heidi'
const a = state
state.name = 'heidi2'
a === state // true
데이터 타입이 객체일때 내용이 바뀌면 변경사실을 체크할 수 없다.
그래서 객체의 내용을 바꿀 때 ...연산자와 this.setState()를 사용한다.
setState는 state변수를 바꿔주는 함수이다.
즉, 리액트는 상태의 값을 바꿔 끼워주는 과정이 필요하다.
<script type="text/babel">
class Counter extends React.Component {
state = {
number : 0,
}
increase = (index) => {
const increase = {
...this.state,
number : this.state.number +index
}
this.setState(increase)
}
decrease = (index) => {
const decrease = {
...this.state,
number : this.state.number -index
}
this.setState(decrease)
}
render(){
return(
<div>
<h3>{this.state.number}</h3>
<button onClick={ ()=> {this.increase(2)} }>+</button>
<button onClick={ ()=> {this.decrease(2)} }>-</button>
</div>
)
}
}
class App extends React.Component {
render(){
return(
<div>
<Counter />
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
1) 일반 Element를 통해 이벤트를 구현하는 경우, 예를들어 이벤트를 사용하는 경우 "" 내부는 js영역이다. 그러므로 리액트에서는 "" 대신 {}로 감싸주어야한다.
2) onClick처럼 cammel형식으로 사용해야한다. js영역은 관계가 없지만 리액트에서는 작동되지 않아 디버깅시 큰 어려움이 생기기도 한다.
3) onClick 함수를 미리 선언하지 않고 render 안에 두면 클릭하지 않아도 실행된다. 미리 선언하거나, 익명함수 형식으로 작성하도록 하면 문제가 해결된다.
4) 3)의 익명함수 안에 setState()를 사용해주면 값이 변경함에 따라 화면이 바뀐다!!
5) 리액트의 최대 단점 ( 리액트 내 조건부 연산자 사용 규칙 )
ㄴ리액트 내에서는 조건문을 삼항연산자로 사용해야한다.