본문 바로가기
리액트

[React] 옵셔널 체이닝(Optional Chaining)

by 지 요니 2023. 4. 28.

json-server를 활용한 실습을 진행하던 중에 오류가 발생하였다. 

import { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";

function App() {
  const [todos, setTodos] = useState(null);
  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3000/todos");
    console.log("data", data);
    setTodos(data);
  };

  useEffect(() => {
    //db로부터 값을 가져오기
    fetchTodos();
  }, []);
  return (
    <div>
      {todos.map((item) => {
        return (
          <div key={item.id}>
            {item.id} : {item.title}
          </div>
        );
      })}
    </div>
  );
}

export default App;

 

 

✅json-server에서 데이터를 받아오는 작업보다 리턴이 더 빠르게 일어났기 때문이다.

즉, todos값이 도착하지 않았는데 map함수가 실행되었기 때문에 null이 나온 것이다. map함수는 todos가 뭔지 모르기 때문에 todos를 null로 처리해준 것이다. 

 

 

이러한 에러가 발생하지 않으려면 && 연산자를 사용하여 todos가 있는 경우에만 todos.map()함수를 실행하도록 코드를 작성하면 에러가 생기지 않는다. 

      {todos && todos.map((item) => {
        return (
          <div key={item.id}>
            {item.id} : {item.title}
          </div>

하지만, AND 연산자를 사용할 경우, 체이닝이 길어지면 코드의 복잡성과 증가하고, 가독성도 떨어지게 된다. 

 

이것을 대신할 수 있는 방법이 옵셔널 체이닝(Optional chaining)이다. 옵셔널 체이닝은 객체 프로퍼티에 
에러없이 안전하게 접근하는 방법이다. 옵셔널 체이닝(?.)을 사용햐게 되면
?.앞의 평가대상이 undefined나 null이면 평가를 멈추고 undefined를 반환하게 된다.

 

🧐  undefined를 반환한다는 것은 어떤 의미를 지니는 걸까?

👉 만약 map함수의 데이터 값이 null이면 map함수 시작 전부터 에러가 발생하게 되고, 코드는 아무런 값을 내뱉지 않고 종료된다.

 

🧐  하지만, 옵셔널 체이닝을 사용한다면 어떻게 될까?

👉 데이터가 null값이어도 에러를 발생하지 않고, undefined라는 리턴값을 주게된다. 따라서 값이 누락될 가능성이 있는 경우에 옵셔널 체이닝을 사용하면 프로그램의 안정성을 높일 수 있고 보다 간단하게 표현할 수 있게된다. 이러한 처리를 통해 비동기 처리와 비슷한 효과를 낼 수 있다고 한다. 

 

오류났던 코드를 아래와 같이 수정하면 

import { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";

function App() {
  const [todos, setTodos] = useState(null);
  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3000/todos");
    console.log("data", data);
    setTodos(data);
  };

  useEffect(() => {
    //db로부터 값을 가져오기
    fetchTodos();
  }, []);
  return (
    <div>
      {todos?.map((item) => {
        return (
          <div key={item.id}>
            {item.id} : {item.title}
          </div>
        );
      })}
    </div>
  );
}

export default App;

 

에러가 발생하지 않고 정상적으로 값이 잘 나오는 것을 확인할 수 있다!!😉

댓글