모든 컴포넌트에 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
,

[React] TypeError: Cannot read property 'map' of undefined


에러가 빈번하게 나온다.


이것의 의미는 map을 할 수 없다는 것이다.


state 등에 있던 배열이 이동했거나 삭제되어 


.map을 사용할 수 없을 때 이런 에러가 발생한다.


따라서, 


xxx.map이라면


xxx가 어디있는지 체크해줘야 한다.

Posted by sungho88
,

부모 컴포넌트에서 자식 컴포넌트로 데이터를 넘겨려면

 

props를 사용한다고 했다.

 

부모(App.js)에서 아래와 같이 배열을 선언한다.

 
const movies = [
{title:"Oldboy", view:"2000"},
{title:"Star Warz", view:"5000"},
{title:"Mad Max", view:"7000"},
{title:"Inception", view:"12000"}
 
]

 

기존에는 화면에 나오는지 테스트하기 위해 

 

render() 내 다음과 같이 작성했었다.

 

 
     <Movie title={movies[0]}/>
<Movie title={movies[1]}/>
<Movie title={movies[2]}/>
<Movie title={movies[3]}/>

 

이렇게 작성을 했다면, Movie 컴포넌트가 정상적으로 화면에 4번 출력될 것이다.

 

물론, Movie에서 this.props.title로 받아주었을때 말이다

 

return (
<div>
<h3>Movie title is a {this.props.title}</h3>
</div>
)

 

하지만, 이렇게 일일히 Movie 태그를 작성하는 것은 비효율적이다. 만약 데이터가 1000개라면?

 

1000번 복붙을 해야할 것이다. 이것은 말이 안된다.

 

또한, 몇 개를 사용할 지 모르는 경우가 있다. 이럴 경우 어떻게 할까?

 

마치 for문, while문을 안 쓰고 배열을 일일히 생성하는 것과 동일하다.

 

이 때 사용하는 것이 바로 map()함수이다.

 

이것은 자바스크립트 문법이므로 모든 배열은 map함수를 갖고 있기때문에 그냥 사용하면 된다.

 

 
{movies.map(movie => {
return <Movie title={movie.title} view={movie.view} />
})}

 

movies 배열을 가져와서 mapping을 한 뒤, 새로운 배열을 만든다..

 

요소는 movies 배열 안에 있는 <Movie>가 될 것이다.

 

이렇게 하면, movies 배열안에 들어있는 갯수만큼 출력된다.

 

그런데 말입니다.

 

정상적으로 나오긴 하지만, 갑자기 구글 개발자 콘솔에서 에러가 보이기 시작한다.

 

기존에 복붙할때는 보이지 않던 에러이다.

 

Each child in an array or iterator should have a unique "key" prop.

 

 

array안에 있는 차일드들은 고유한(unique) key prop을 가져야 한다.

 

리액트에서는 엘리먼트가 많을 경우 고유한 key라는 것을 정해주어야한다.

 

그래서, movies 배열에 id라는 것을 하나 더 만든후, 중복되지 않게 작성해주자.

 

const movies = [
{id:1, title:"Oldboy", view:"2000"},
{id:2, title:"Star Warz", view:"5000"},
{id:3, title:"Mad Max", view:"7000"},
{id:4, title:"Inception", view:"12000"}
]

 

 

{movies.map(movie => {
return <Movie title={movie.title} view={movie.view} id={movie.id} />
})}

 

이렇게 했는데, 에러가 없어지지 않는다.

map도 일부를 변경해주어야한다.

 

{movies.map((movie, index) => {
return <Movie title={movie.title} view={movie.view} key={index} />
})}

 

위와 같이 변경해주면, 에러가 사라진다.

 

 

props의 형태를 지정해두고 싶을때는 어떻게 할까?

 

제목title인데 숫자나 true/false가 출력된다거나,

관객수view인데 문자열만 출력되다거나 하는 상황을 방지하려면 어떻게 할까?

 

바로 props-type이라는 패키지를 설치해주면 된다.

 

$ yarn add prop-types

또는

$ npm install prop-types 

 

 

https://www.10000duck.com/view_duck/43

 

10000duck - KBS 동행 제325화 유라의 행복한 부엌

온라인 모금함을 통해 기부하세요.

www.10000duck.com

 

Posted by sungho88
,