React + Typescript (5) .bind() 사용하기

gyojinnK·2024년 1월 23일

리액트 플러스

목록 보기
11/11
post-thumbnail

Todo 리스트를 만드는 작은 프로젝트를 만드는 중이다.
상위 컴포넌트에서 todo 항목이 들어간 배열을 관리하고 하위 컴포넌트(Todo 항목 컴포넌트와 Todo 항목 추가 컴포넌트 등)에서 CRUD를 진행한다.

이번에 구현 중인 기능은 하나의 Todo 항목을 클릭하면 해당 항목을 삭제하는 기능이다.

// App.tsx
function App() {
    const [todos, setTodos] = useState<Todo[]>([]);

    ...

    const deleteTodoHandler = (targetId: string) => {
        setTodos((prev) => {
            return prev.filter((todo) => todo.id !== targetId);
        });
    };

    return (
        <div>
            <NewTodo onAddTodo={addTodoHandler} />
            <Todos items={todos} onDeleteTodo={deleteTodoHandler} />
        </div>
    );
}

위 코드는 최상위 컴포넌트이다.
deleteTodoHandler 함수를 props chaining 통해 항목 컴포넌트에 전달하여 처리할 것이다.

함수를 chaining 해보자
App.tsx에서 onDeleteTodo prop으로 Todos 컴포넌트로 함수를 전달한다.

참고로 컴포넌트의 구조는 이러하다

  • App.tsx
    • todos.tsx
      • TodoItem.tsx
      • TodoItem.tsx
      • ...

이후 추가한 props의 타입을 명시하여 리액트에게 알리고 TodoItem 컴포넌트로 전달한다.

// Todo.tsx
const Todos: React.FC<{ items: Todo[]; onDeleteTodo: (id: string) => void }> = (
    props
) => {
    return (
        <ul className={classes.todo}>
            {props.items.map((item) => (
                <TodoItem
                    key={item.id}
                    text={item.text}
                    onDeleteTodo={props.onDeleteTodo.bind(null, item.id)}
                />
            ))}
        </ul>
    );
};

export default Todos;

여기서 포인트는 .bind()를 사용하여 전달한다는 것이다.

bind()

bind()는 자바스크립트에서 제공하는 메서드로 이 메서드를 사용하면 실행할 함수를 미리 설정할 수 있다.
첫번째 인자는 해당 키워드가 무엇을 가르키는지 지정한다 (호출할 함수 안에서).
지금과 같은 상황에서 이 값은 중요하지 않아 null로 처리했다.
두번째 인자는 해당 함수 즉, onDeleteTodo 함수가 매개변수로 받게되는 값이다.
본 애플리케이션에서는 클릭한 TodoItem의 id를 가져와 해당 id를 배열에서 제외시킬 것이기 때문에 id값으로 설정한다.

이렇게하면 id값을 추출하기 위해 다른 state가 props를 생성하거나 만들지 않아도 된다.
bind()는 다른 목적으로도 활용되지만 본 코드에서는 매개변수를 쉽게 전달하기 위해서 bind()를 채택했다.

특정 요소를 선택하고 이를 상위 요소에서 처리할 때 bind()를 이용하여 추가적인 변수 선언 없이 현재 컴포넌트의 특정 값을 넘길 수 있어서 앞으로도 종종 채택할 것 같다~

profile
기록하고 꺼내보고

0개의 댓글