본문 바로가기
프로그래밍/자바스크립트

프로그래밍 「 자바스크립트 편」React를 사용할 때 4가지 실수

by grapedoukan 2023. 6. 16.
728x90

1.# 숫자 0과 "&&"를 조건으로 사용하여 목록 렌더링

문제 설명

어쩌면 목록을 렌더링해야하는 코드를 작성했을 수도 있지만, 그 전에는 array.length 및 && 기호를 사용하여 목록을 렌더링할지 여부를 결정하는 경우가 많았습니다.

const renderList = () => {
  const [ dataList, setDataList ] = useState([])

  return dataList.length && <List } />
}

dataList의 길이가 0 일 때, 우리는 아무것도 렌더링하지 않을 것이라고 생각합니다. 실제로 0을 렌더링합니다.

솔루션

그것은 JavaScript의 언어 기능 중 하나 인 버그가 아닙니다.React

const arr = []
const result = arr.length && 'fatfish'

console.log(result) // 0

그렇다면이 문제를 어떻게 해결할 수 있습니까? 결국, 우리는 아무것도 렌더링하지 않기를 원합니다.

const renderList = () => {
  const [ dataList, setDataList ] = useState([])

  return dataList.length > 0 && <List } /> // solution 1
  // return !!dataList.length && <List } /> // solution 2
}

콘텐츠를 렌더링하기 위한 조건으로 부울 값을 사용하는 것은 React에서 현명한 선택입니다

2.# 상태 직접 수정

문제 설명

내가 배우기 시작했을 때, 나는 종종 를 통해 데이터를 수정하는 대신 직접 수정합니다.ReactstatesetState

상태를 직접 수정해도 구성 요소의 렌더링이 트리거되지 않기 때문에 이는 좋지 않습니다.

따라서 다음 코드에서는 num을 몇 번이나 클릭해도 0으로만 렌더링됩니다

const Demo = () => {
  const [ num, setNum ] = useState(0)
  const onClick = () => {
    num += 1
    setNum(num)
  }

  return (
    <div>
      <p>Num: {num}</p>
      <button onClick={onClick}>Increment</button>
    </div>
  )
}

솔루션

setState를 사용하여 데이터를 업데이트해야 하며 함수를 수신하고 콜백 함수에서 이전 값을 가져올 수 있습니다.

const Demo = () => {
  const [ num, setNum ] = useState(0)
  const onClick = () => {
    setNum((prevNum) => prevNum + 1)
  }

  return (
    <div>
      <p>Num: {num}</p>
      <button onClick={onClick}>Increment</button>
    </div>
  )
}

3.# 이전 값을 잘못 가져오기

문제 설명

사용하기 전에 나는 내 작업에서 개발 언어로 사용했다. 에서는 변수를 설정한 직후 변수의 최신 값을 얻을 수 있습니다.ReactVueVue

<template>
  <div class="demo">
    <p>Num: {{ num }}</p>
    <button @click="onClick">Increment</button>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  data () {
    return {
      num: 1,
    }
  },
  methods: {
    onClick () {
      this.num += 1
      console.log(this.num) // 2
    }
  }
}
</script>

나는 같은 것을 얻을 수 있다고 생각했다.React

const Demo = () => {
  const [ num, setNum ] = useState(0)
  const onClick = () => {
    setNum((prevNum) => prevNum + 1)
    console.log(num) // num is always the old value
  }

  return (
    <div>
      <p>Num: {num}</p>
      <button onClick={onClick}>Increment</button>
    </div>
  )
}

솔루션

사실, 는 비동기식이며, 이는 호출 직후 최신 값을 얻을 수 없음을 의미합니다.

 

num이 변경된 후에 작업을 수행하려는 경우 를 사용해 볼 수 있습니다.useEffect

const Demo = () => {
  const [ num, setNum ] = useState(0)
  const onClick = () => {
    setNum((prevNum) => prevNum + 1)
  }

  useEffect(() => {
    console.log(num) // When num changes, the latest value of num will be printed out
  }, [ num ])

  return (
    <div>
      <p>Num: {num}</p>
      <button onClick={onClick}>Increment</button>
    </div>
  )
}

4.# 사용 중 정리되지 않은 부작용효과

문제 설명

매 초마다 1을 num에 추가하는 타이머를 켰습니다.

그러나 타이머를 지우는 코드를 작성하지 않았으므로 구성 요소가 언로드되거나 사용되지 않더라도 타이머는 항상 메모리에 존재할 수 있습니다. 이로 인해 메모리 누수가 발생하여 결국 애플리케이션 성능이 저하될 수 있습니다.

const Demo = () => {
  const [ num, setNum ] = useState(0)
  useEffect(() => {
    const timer = setInterval(() => {
      setNum((prevNum) => prevNum + 1)
    }, 1000)
  }, [])

  return (
    <div>
      <p>Num: {num}</p>
    </div>
  )
}

솔루션

타이머 지우기, 이벤트 리스너 제거 등과 같은 필요한 정리 작업을 수행해야 합니다.

const Demo = () => {
  const [ num, setNum ] = useState(0)
  useEffect(() => {
    const timer = setInterval(() => {
      setNum((prevNum) => prevNum + 1)
    }, 1000)
    return () => {
      clearInterval(timer) //  Clear Timer
    }
  }, [])

  return (
    <div>
      <p>Num: {num}</p>
    </div>
  )
}
728x90