button
wanted
pre-on-boarding

원티드 프리온보딩 과제 - 9일차

숫자 난수 생성

const arr = new Uint32Array(6);
const id = parseInt(crypto.getRandomValues(arr).join(''));

오늘 중간에 난수를 id로 만들기 위해 찾아보던 중에 발견한 방법이었습니다. 하지만 코드에 반영하지 않았습니다.

Context

import {
  createContext,
  ReactNode,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react';
import { createTodo, deleteTodo, getTodos, updateTodo } from '../api';

/**
 * @todo 1. 불필요한 리랜더링 이슈 해결
 * @todo 2. reducer로 리팩토링하기
 */
function useTodosSource() {
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    const syncTodos = async () => {
      const todos = await getTodos();
      setTodos(todos);
    };
    syncTodos();
  }, []);

  const handleCreateTodo = useCallback(async (todo: string) => {
    const { id, userId } = await createTodo(todo);
    setTodos((prev) => [...prev, { id, todo, isCompleted: false, userId }]);
  }, []);

  const handleUpdateTodo = useCallback(
    async (id: number, { todo, isCompleted }: Omit<Todo, 'id' | 'userId'>) => {
      setTodos((prev) =>
        [...prev].map((todoItem) =>
          todoItem.id === id ? { ...todoItem, todo, isCompleted } : todoItem
        )
      );
      await updateTodo(id, { todo, isCompleted });
    },
    []
  );

  const handleDeleteTodo = useCallback(async (id: number) => {
    setTodos((prev) => [...prev].filter((todoItem) => todoItem.id !== id));
    await deleteTodo(id);
  }, []);

  const contextValue = useMemo(
    () => ({
      todos,
      handleCreateTodo,
      handleUpdateTodo,
      handleDeleteTodo,
    }),
    [todos, handleCreateTodo, handleUpdateTodo, handleDeleteTodo]
  );

  return contextValue;
}

const todoCTX = createContext<ReturnType<typeof useTodosSource>>(
  {} as unknown as ReturnType<typeof useTodosSource>
);

export function useTodos() {
  return useContext(todoCTX);
}

interface TodosProviderType {
  children: ReactNode;
}

function TodosProvider({ children }: TodosProviderType) {
  return (
    <todoCTX.Provider value={useTodosSource()}>{children}</todoCTX.Provider>
  );
}

export default TodosProvider;
  • CRUD를 구현할 수 있지만 문제가 있습니다.
  • 리랜더링 문제입니다. 너무 많습니다.
  • 다른 문제는 버그가 있습니다. 삭제를 하면 check가 밀려납니다. 왜 발생하는지 모르겠습니다.
  • 일단 mrege하고 prop drilling이라도 해서 디버깅을 시도해보겠습니다.
  • 또 useReducer로 리팩토링도 시도해볼 것입니다.