state : 컴포넌트 내부에서 바뀔 수 있는 값
props : 부모 컴포넌트가 설정하는 값, 자식 컴포넌트는 props를 읽기 전용으로만 사용할 수 있음
하향식 데이터 흐름 (단방향식 데이터 흐름)
import { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
};
}
}
import { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
};
}
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
)
}
}
import { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
fixedNumber: 0
};
}
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
)
}
}
import { Component } from 'react';
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0
};
render() {
const { number, fixedNumber } = this.state;
return (...);
}
}
this.setState((prevState, props) => {
return {
// 업데이트하고 싶은 내용
}
})
<button
onClick={() => {
this.setState(prevState => {
return {
number: prevState.number + 1
};
});
}}
>
+1
</button>
// 화살표 함수에서 값을 바로 반환하고 싶으면 {}를 생략 가능함
<button
onClick={() => {
this.setState(prevState => ({
number: prevState.number + 1
}));
}}
>
+1
</button>
<button
onClick={() => {
this.setState(
{
number: number + 1
},
() => {
console.log('setState 호출');
console.log(this.state);
}
);
}}
>
+1
</button>
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
import { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕하세요');
const onClickLeave = () => setMessage('안녕가세요');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
</div>
);
};
export default Say;
import { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const [color, setColor] = useState('black');
const onClickEnter = () => setMessage('안녕하세요');
const onClickLeave = () => setMessage('안녕가세요');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<button style={{ color: 'red' }} onClick={() => setColor('red')}>red</button>
<button style={{ color: 'green' }} onClick={() => setColor('green')}>green</button>
<button style={{ color: 'blue' }} onClick={() => setColor('blue')}>blue</button>
</div>
);
};
export default Say;
// bad
this.state.number = this.state.number + 1;
const [object, setObject] = useState({ a: 1, b: 1 });
object.b = 2;
// good
this.setState({ number : number + 1});
const [object, setObject] = useState({ a: 1, b: 1 });
setObject({ ...object, b: 2});
const object = { a: 1, b: 2, c: 3 };
const nextObject = { ...object, b: 2};
const array = [
{id: 1, value: true},
{id: 2, value: true},
{id: 3, value: false},
];
const nextArray = array.concat({ id: 4});
nextArray.filter(item => item.id !== 2);
nextArray.map(item => (item === 1 ? {...item, value: false} : item));