모든 컴포넌트에 state가 있어야 하는것은 아니다.


어떤 컴포넌트는 state정보가 없는 stateless 컴포넌트도 있을 수 있다. 


이들은 오직 props만 갖고 있다.


그리고,


stateless 컴포넌트는 클래스 형태가 아니라 함수(functional) 형태로 작성해야 한다.


stateless = 함수형 컴포넌트

state = 클래스 컴포넌트



class NoState extends Component {
render() {
return (
<p>MoviePoster 컴포넌트입니다</p>
)
}
}

export default NoState;


위와 같이 state를 사용하지 않는 컴포넌트는 클래스를 사용하지 않고


함수형 컴포넌트를 사용한다.


이 컴포넌트들은 그냥 return을 하기 위해 존재한다.(=화면에 뷰를 보여주기 위해 존재한다)


따라서, state뿐만 아니라 리액트 컴포넌트 라이프 사이클조차 필요없다.


사용 못 한다. 사용 안 하는것이 아니라 할 수 없다.



function NoState({title}) {
return(
<img src={title} alt="This is Title image"/>
)
}



정리


함수형 : state 사용 불가 / render() 함수도 없고, 라이프 사이클도 존재하지 않음 / 오직 return만 갖고 있음.

클래스 : state 사용 가능 / render() 함수가 존재, 라이프 사이클도 존재함.



+ 추가


클래스를 함수형 컴포넌트로 변형할때,



export default Movie


도 제거하는 경우가 발생한다.


하지만, 이것은 컴포넌트를 외부에서 사용할 수 있게 선언하는 문장이므로 삭제하면 안된다.


함수형이던, 클래스 형태건 둘 다 컴포넌트이기 때문이다.



이러한 에러가 발생한다. 그렇게 되면 


컴포넌트 하단에 


export default 컴포넌트명


이 존재하는지 확인해 볼 필요가 있다.

Posted by sungho88
,

state는 무엇인가?


- 컴포넌트 내부에서 자체적으로 읽고, 업데이트할 수 있는 값을 사용하기 위해 state가 존재한다.

- 모든 리액트 컴포넌트 안에 존재할 수 있는 오브젝트이다(필수는 아니므로 없어도 된다)

- 컴포넌트 내 state가 변경될때마다 해당 컴포넌트는 다시 렌더링된다(=render()함수가 실행된다)


state를 선언하는 방법


원래는 생성자(constructor) 안에 선언해야 하지만, 생성자 밖에 다음과 같이 선언할 수 있다.


state = {
greeting:"Hello World"
}


이런 형식으로 작성을 하고, 사용할때는 


render() {
return (
<div className="App">
<h1>Helio</h1>
{this.state.greeting}
</div>
);
}


이런식으로 호출해서 사용하며 결과는 다음과 같다.




state를 수정하는 방법(업데이트 하는 방법)


this.state.greeting = "Hello Jang";    


쉽게 생각하면 이렇게 직접 수정하면 될 것 같지만 직접적인 접근은 절대 안된다.


직접적으로 변경하면 render() 설정들이 작동을 하지 않으므로 값은 바뀌지 않는다(리-렌더링이 되지 않는다)


위와같이 코드를 실행하면 다음과 같은 경고가 발생한다.


Compiled with warnings.


./src/App.js

  Line 19:  Do not mutate state directly. Use setState()  react/no-direct-mutation-state


그러므로,  다이렉트로 state값을 수정해서는 안 되며, 


아래와 같이 setState()를 사용하여 값을 변경해야 한다.



this.setState({
greeting: "Hello Jang"
})


변경을 하려면, 이렇게 setState()를 사용한다. 그래야 render()가 정상적으로 리렌더링된다.


즉, setState가 사용되어 state를 변경하면 render()함수가 정상적으로 재작동하게 되며,


state의 값은 새롭게 변경된다. this.setState({}) 으로 기억해두자. 


메소드 ()안에 객체{} 값이 들어가니까..


항상 아래와 같은 구조를 지닌다.


this.setState({

...

.....

})


setState()메소드의 역할은 파라미터로 전달받은 필드를 업데이한 뒤, 컴포넌트가 리렌더링하게 한다.


만약, 렌더링 된 후 몇 초 후에 state값을 바꾸고 싶다면 어떻게 할까?


자바스크립트 문법 중 setTimeout() 함수를 사용하면 된다.


componentDidMount() {
setTimeout(() => {
this.setState({
// state 변경
})
}, 2000) // 시간. 2초 후 실행
}


위 코드는 setTimeout() 함수를 사용하여 2초 후에 setState()메소드를 사용하여 state를 변경하는 코드이다.


setTimeout() 함수를 사용하여 state 내 배열에 항목을 추가하려면 어떻게 할까?


state = {
person:[
{id:1, name:"JANG", age:"21"},
{id:2, name:"HONG", age:"32"},
{id:3, name:"KIM", age:"41"},
{id:4, name:"PARK", age:"55"}
]
}


componentDidMount() {
setTimeout(() => {
this.setState({
movies: [
...this.state.person,
{
name:"SUNGHO",
age:"120",
id:5
}
]

})
}, 2000)
}


2초 후에 person 목록에 추가된다.


그런데, 주의할 점이 있다. 


배열안에


...this.state.person


을 써줘야한다. 이것을 해야 기존 배열이 살아있고, 그 뒤에 추가가 되는 것이다.


이것을 써주지 않으면 person이라는 배열은 기존값들이 전부 사라지고 추가한 항목만 남게 된다.



state와 prop의 가장 큰 차이점은


props는 부모 컴포넌트가 설정하고, 해당 컴포넌트는 받아서 사용하는 "읽기 전용",


state는 해당 컴포넌트가 자체적으로 지난 값으로, 읽을수 있을뿐만 아니라 값을 업데이트하는 기능.

 

Posted by sungho88
,