본문 바로가기
Front-end/React

[React] Props 로 콜백 함수 전달하기 / 어떨때 Props로 콜백 함수를 전달해야 하는가?

by 질서정연_ 2022. 10. 29.

Props 로 콜백 함수 전달하기

 

개념 정리

Props 란 ? 

react에서 props는 데이터를 한 컴포넌트에서 다른 컴포넌트로 전달 할 때 사용된다. (부모 -> 자식 )

CallBack Function  이란? 

정의:

프로그래밍에서 콜백 또는 콜백함수는 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 

콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수도 있고, 아니면 나중에 실행할 수도 있다. 

 

이벤트는 페이지가 로드되거나 유저가 click, hover, change 등의 상호작용을 했을 때  등 그 밖의 여러가지 상황에서 발생한다. 

이벤트에 반응하기 위해서 함수를 공급해야한다. 

이벤트가 발생했을 때 불려 질 함수를 콜백함수라고 한다. 

React Data Flow

data는 부모에서 자식으로만 전달 될 수 있다.

형제 컴포넌트에게는 데이터를 전달 할 수 없다. 

그래서 형제끼리 공동의 state를 공유하고 싶다면 state를 부모에게 주고 그걸 자식들이 받을 수 있게 한다. 

이걸 Lifting State Up 이라고 한다. 

 

해결하고 싶었던 상황  

리액트를 복습하면서 콜백 함수를 넘겨 줄 때 너무 답답하고 왜 에러가 발생하는지 이해하지 못했다 .

내가 제대로 공부를 하지 않고 넘어가서이기 때문에 반성하며 꼼꼼하게 공부를 한다. 

 

최상위 컴포넌트 App 에서 data 수정을 위한 onEdit 을 만들어 props로 

DiaryList 에게 전달했다. 그 다음 DiaryList의 자식인 DiaryItem Component 에 onEdit을 Props로 전달했다. 

 

작성 완료 버튼을 눌렀을 때 전달 받은 onEdit 에 DiaryList의 id와 content를 넘겨줘서 그 내용이 최종적으로 App 컴포넌트의 dataList에 반영되기를 바랬다.

 

app.js에서 선언한 onEdit 함수 

const onEdit = (targetId, newContent) => {
    setData(
      data.map((it) => it.id === targetId ? { ...it, content: newContent } : it)
    )
  }

데이터를 객체 배열로 쓰고있었기 때문에 setData(data.map())으로 데이터 변경을 시켜줘야한다는 점 .. 명심 또 명심할 것

 

DiaryItem Component

<button onClick={onEdit(id, content)}>수정 완료</button>

 

Diary Item 에서 저렇게 이벤트를 사용하려고 했는데 계속 에러가 났다. 

Warning: Cannot update a component (`App`) while rendering a different component ....

계속해서 생겨나는 경고메세지..

 

결론은 당연히 에러가 날 수 밖에 없다. onEdit(id, content) 를 한건 함수를 실행했다는 뜻이니까

이벤트가 발생하기도 전에 렌더링 과정에서 저 함수가 실행되는것이다. 

 

그렇게 되면 onEdit 함수는 state를 변경시키는 거니까 state가 변경되니 또 렌더링 -> 또 렌더링 -> 또 렌더링 .. 무한 렌더링이 된다. 그래서 저 에러가 나는것 ~ 

 

그런데 callback 함수를 다른 함수로 감싸주면 페이지가 렌더링 될 때 함수 선언이 onClick 안에 저장되게 된다.

 

const handleEdit = () => {
        if (localContent.length < 5) {
            localContentInput.current.focus();
            return;
        }

        if (window.confirm(`${id}번째 일기를 수정하시겠습니까?`)) {
            onEdit(id, localContent);
            toggleIsEdit();
        }
    }
    
   return (
   	<button onClick={handleEdit}>수정 완료</button>
   );

 

이렇게 props로 받은 onEdit 콜백 함수를 

DiaryItem 에서 handleEdti 함수를 만들어주고 그 안에 onEdit 을 넣어주면 해결 ~~!! 

이런 과정을 encapsulate 라고 부른다. 캡슐화 하는 것 ~ (ง •_•)ง

 

어떨 때 CallBack Function 을 넘겨줘야 하는가 ?

다른 컴포넌트에게 정보를 넘겨 줄 때 사용할 수 있는 두가지 방법이 있다. 

첫번째, 부모에서 자식으로 props를 통해 넘겨줄 수 있다. 

그런데 자식에서 부모로 데이터 흐름을 전달하고 싶다면 ?

state를 자식에게 전달하는 것 보다 부모는 콜백 함수를 전달 할 수 있다.

콜백 함수는 나중에 실행되며 보통 자식 컴포넌트와의 상호작용이 있다.

 

이런 콜백함수의 목적은 부모 컴포넌트의 state를 변경하기 위해서이다. 

 

 

부모컴포넌트에서 state가 만들어진다. 

 

위의 예제처럼 부모 component 에 data state가 있다고 하자. 

자식 컴포넌트 diaryItem 에서 이 data state를 변경하고 싶다면 

부모 component에서 data state를 변경 할 callback function 을 만들어 자식에게 전달하고 , 자식이 이를 사용하게 하면 된다. 

 

자식이 수정 완료 버튼을 누르게 되면 onEdit 함수가 실행되고 이것은 app의 state인 data 를 변경한다. 자식 component가 부모의 state 에게 영향을 주기 위해서 callback function 을 자식에게 props로 주는것이 필요하다.  

 

 

참조

 

https://htmldog.com/guides/javascript/intermediate/events/

 

Events and Callbacks | HTML Dog

Events and Callbacks In the browser most code is event-driven and writing interactive applications in JavaScript is often about waiting for and reacting to events, to alter the behavior of the browser in some way. Events occur when the page loads, when use

htmldog.com

https://medium.com/@thejasonfile/callback-functions-in-react-e822ebede766

 

Callback functions in React

It had been a while since I built anything in React, so I decided to test out my skills and see how long it would take to build the most…

medium.com

 

그럼 모두 즐코 ~ 🦄

 

 

 

댓글