FRONTENDSCHOOL6 / ready-act

멋쟁이사자처럼 파이널프로젝트 16조
MIT License
0 stars 4 forks source link

[R09M App] CreateRoom 페이지 - useContext 사용 이슈 #36

Closed jellyjoji closed 1 year ago

jellyjoji commented 1 year ago

내용

기존에 forwardRef 를 사용하여 form data 페이지와 연결시켰던 코드를 useContext를 사용하여 리팩토링 중입니다. useContext 를 사용하요 select option 에서 선택된 결과값을 useContext(AppContext) 데이터에 넣으려고 시도중입니다. 그런데 selection option 중 선택된 결과값을 setSelectedCategory 에 넣고 콘솔에 로그를 찍어보니 undefined 으로 뜹니다.

useContext 를 사용하여 선택된 결과값을 append 하려면 어느 부분을 고쳐야 할까요?

제가 표현하려는 구조는 아래 그림과 같습니다. 선택된 Category 결과값을 forwardRef 가 아닌 useContext를 사용하여 form 에 입력하려고 합니다. image

CategoryDropdown.jsx

import { useId, useContext, useState, useEffect } from 'react';
import { category } from '../../data/category';
import { AppContext } from '../../App';

function CategoryDropdown({ className, title }) {
  const { id } = useId();
  const { updateCreateRoomForm } = useContext(AppContext);
  const [selectedCategory, setSelectedCategory] = useState();

  useEffect(() => {

    async function readCategoryList() {
      try {
        const categoryList = category.map((list) => list.title);
        console.log(categoryList);
        console.log(setSelectedCategory);

      } catch (error) {
        console.error(error);
      }
    }

    readCategoryList()

    updateCreateRoomForm('category', selectedCategory);
    console.log(selectedCategory);
  }, []);

  return (
    <div>
      <label htmlFor={id}>{title}</label>
      <select
        value={selectedCategory} onChange={(e) => setSelectedCategory(e.target.value)}
        id={id}
        className={className}
        name="category"
        defaultValue="전체"
      >
        {category.map((list) => (
          <option key={list.title} value={list.title}>
            {list.title}
          </option>
        ))}
      </select>
    </div>
  );
}

export default CategoryDropdown;

※ 댓글에 이슈 해결 완료 후 결과 또는 해결 과정 이미지 첨부

jellyjoji commented 1 year ago

상태는 스냅샷.

리액트 상태는 스냅샷처럼 작동합니다. 그러므로 상태는 다음 렌더링에서 값이 변경됩니다. 상태 값 변경을 감지해 처리하려면 useEffect 훅을 사용해야 합니다. 아래 코드를 참고하세요.

CategoryDropdown.jsx

function CategoryDropdown({ className, title }) {
  const { id } = useId();
  **const { updateCreateRoomForm } = useContext(AppContext);**
  **const [selectedCategory, setSelectedCategory] = useState();**

  **useEffect(() => {**
        // selectedCategory 상태가 변경되면 폼 category 상태 변경
    **updateCreateRoomForm('category', selectedCategory);
  }, [selectedCategory]);**

  return (
    <div>
      <label htmlFor={id}>{title}</label>
      <select
        value={selectedCategory}
        **onChange={(e) => setSelectedCategory(e.target.value)}**
        id={id}
        className={className}
        name="category"
        defaultValue="전체"
      >
        {category.map((list) => (
          <option key={list.title} value={list.title}>
            {list.title}
          </option>
        ))}
      </select>
    </div>
  );
}

CreateRoom 컴포넌트에서 변경된 카테고리 상태를 읽으려면 다음과 같이 작성합니다.

CreateRoom.jsx

const handleCreate = async (e) => {
  e.preventDefault();

  **const categoryValue = createRoomForm.category;**

    // ...

  const data = new FormData();

  **data.append('category', categoryValue);**

    // ...
};

적용 결과

1

이제 방만들기 카테고리 상태를 변경하면 정상적으로 반영됩니다. 😃

1.gif