react 조건부렌더링

박은정·2021년 9월 9일
0

TIL

목록 보기
22/70

이러한 코드를 실행하게 되면 아래와 같은 에러가 발생한다

TypeError: Cannot read property 'map' of undefined

일단 오류메시지를 해석한다면,
undifined에 map() property를 읽을 수 없다는 건데

property는 object라는 자료형 안의 요소를 부르는 말인데
Number, String, undefined 자료형에는 property가 없다
어떤 객체의 map이라는 property를 읽으려고 했는데
그 객체가 undefined이기 때문에 읽지 못한다는 뜻이다

{this.state.data.message.map(msg) =>

문제의 원인

이부분이 에러가 발생한 부분이라고 나오는데
위의 지식을 생각하면 this.state.data.message 가 undefined라는 것을 알 수 있다

setState()를 통해 this.state.data가 빈 객체인 상태에서 response로 업데이트 해주기는 하지만

LifeCycle 메서드의 순서를 생각한다면
constructor(), render()가 호출되었을 때 this.state.data는 빈 객체이기 때문에 이러한 빈 객체에 특정 property가 들어간다면 undefined가 발생한다

해결방법

this.state.data가 undefined가 아닐 때에만 렌더링되도록 조건을 설정한다

this.state.data !== undefined가 아닐 때만 렌더가 되도록 구현되었지만

render를 통해 아무것도 반환되지 않는데, 이러한 이유는 return되는 state가 없을 때 에러가 발생한다
혹시 아무것도 렌더링하고 싶지 않다면 null을 반환하라는 에러메시지가 발생한다

  1. 첫번째 render()가 호출될 때에는
    date = 빈 객체,
    this.state.data.message = undefined 이다
  1. 그다음에 componentDidMount가 호출되었을 때에는
    data = {message: Array(7)} 라는 response값,
    this.state.data.message = Array(7) 의 결과를 알 수 있다

따라서 array자료형은 map() 메서드를 실행할 수 있어서 화면에 데이터가 나오게 된다

코드 리팩토링

if()문을 삼항연산자로 변경할 수 있고
undefined는 false이기 때문에 다음과 같이 코드를 적을 수 있다

return this.state.data.message ? (render될 return) : null ;

한편 조건이 성립될 때만 렌더링이 되도록 설정하는 것이라
null의 값은 굳이 지정하고 싶지 않을 때에는
&& 연산자 를 통해 작성하고 바깥 부분을 <Fragment>로 감싸줘야 위와같은 undefined map() 에러 가 발생하지 않는다

react에서 if문 대신에 삼항연산자를 사용하는 이유

JSX문법에서는 구문은 사용하지 못하는 반면, 값으로만 입력을 해야되는데

  • if, else 구문이라 사용이 안되고
  • 삼항연산자는 어떠한 값으로 담을 수 있는 표현식이기 때문에 사용이 가능하다

if, else 구문은 어떠한 값이 될 수 없는데 삼항연산자는 변수에 담을 수 있다

const a = if {
	let a = b
    } else {
    
    }

const b = true ? 1 : 0

질문타임!

💡 this.state.date.message를 빈 문자열로?

한편, this.state.date.message 를 빈문자열로 설정하면 &&연산자를 안 써도 에러는 발생하지 않기는 한데
원래 this.state.date.message 가 string이었다가 데이터를 받게 되면 array가 들어오면서 데이터형태가 변경하게 되어서
추후에 다른 사람이 코드를 보면서 예측하기 힘들고
this.state.date.message 에 어떤 데이터가 들어올지 모르는 상태에서 빈문자열로 초기값을 설정하는 것은 바람직하지 않다

단축평가방법 &&, ||

condition1 = false
condition2 = true 
condition1 && condition2 -> false

앞의 조건이 이미 false이기 때문에
뒤 조건은 쳐다보지도 않고 바로 false를 반환하고

condition1 = true
condition2 = true
condition1 && condition2 -> true

앞의 조건이 true일 때에는 뒤의 조건도 읽고 뒤의 조건을 반환하게 된다

condition1 = true
condition2 = 'abc'
console.log(condition1 && condition2) -> 'abc'

출처 : https://velog.io/@najiexx/JavaScript-%EB%8B%A8%EC%B6%95-%ED%8F%89%EA%B0%80


💡 componentDidMount()에서 fetch()함수 두번 호출해도 되나?

아무런 지장이 없다
componentDidMount()은 컴포넌트가 mount될 때 동작하고 싶은 거를 입력하는 것이기 때문에 서로 다른 API데이터를 서버에 요청할 때 두개의 fetch() 함수를 호출하면 된다

다만, 동일한 API 주소에 대해서 fetch() 함수를 두번 사용하는 것은 효율적이지 않다

profile
새로운 것을 도전하고 노력한다

0개의 댓글