취미부자 개발자 로즈🌼
작성일
2022. 10. 7. 06:21
작성자
로즈♡

글 리스트가 있을 때 해당 글을 클릭하면 해당 페이지로 이동이 되는 기능을 만들려고 한다.

props를 통해 데이터를 전달하는 것 까지는 이해가 되는데, 

onClick이벤트에 대한 정리가 잘 되지 않아 이 부분에 대한 흐름만 정리해본다.

 

 

코드는 길어질 수 있으니 import부분과 export 부분 생략 후 작성했다. 

 

 

아래 코드 작성을 해둔걸 한 눈에 볼 수 있게 하나의 이미지로 만들어봤다.


 

🌼 PostListItem.jsx

//PostListItem.jsx

function PostListItem(props){
  const { post, onClick} = props;
  
  return ( 
    <div onClick={onClick}>
      <p>{post.title}</p>
    </div>
  );
}

div를 클릭했을 때 props를 통해 받아온 onClick을 사용한다.

 

🌼 PostList.jsx

//PostList.jsx
//import PostListItem을 해준다. 

function PostList(props){
  const { posts, onClickItem } = props;
  
  return ( 
    <div>
      //📌리스트를 뿌려 줄 땐 이곳에서 map을 사용해서 뿌려준다.
      {posts.map((post, index) => {
      
        return (
          <PostListItem 
            key={post.id} 
            post={post}
            onClick={() => {
              onClickItem(post);
            }}
          />
        );//📌return end
        
      })}//📌map end
    </div>
  );
}

주석이 눈에 띄지 않아 📌표시로 강조해봤다.

리스트는 map으로 뿌려주는데, 그 안에서 PostListItem을 사용하면서 값을 보내준다. 

 

PostListItem에 보내는 값.

1. key : 글을 구분하기 위한 값으로 props에서 받아온 post의 id를 보내준다.

2. post : post 데이터 자체를 보내준다. map으로 뿌렸기 때문에 각각 개별데이터를 받아서 뿌려주는 느낌.

3. onClick : 함수를 사용해서 props에서 받아온 onClickItem함수를 사용하는데, 값은 post데이터를 보내준다.

 

🌼 MainPage.jsx

//MainPage.jsx
//import PostList
//import { useNavigate } from 'react-router-dom'; 
//페이지 이동을 위해사용. 설치 필요.

function MainPage(props){
  const navigate = useNavigate();
  
  return ( 
    <div>
      <PostList 
        post={data}
        onClickItem={(item) => {
          navigate(`/post/${item.id}`);
        }}
      />
    </div>
  );
}

처음 보내는 곳에서는 navigate를 import해서 가져와준다.

 

PostList에 보내는 값.

1. post : import에서 생략했지만, 실제 data를 보내준다. 위 코드 원문에서는 data라는 이름의 json파일을 사용했다.

2. onClickItem : PostList에서 onClickItem을 호출하면서 post를 넣어줬다. 즉 item = post라는 것. item.id를 가져와서 해당 글로 이동을 하게 해준다. 

 

 

 


여기서부터는 단순 나의 생각 정리를 위한 글.

 

 

나름의 해석을 담아 정리하자면.

A-B-C라는 화면이 있고, A에서 B를, B에서 C화면을 보여준다 가정.

1. A에서 B를 사용(화면에 담는다) :  data 보내줄게. onClick을 쓸거면 item을 같이 보내줘. 그러면 내가 그 번호에 대해 이동시켜줄게.

2. B에서 C사용 : A를 통해 받은 데이터가 있는데, C한테는 id는 구분해서 주고, data도 같이 줄게. 너도 onClick쓸거면 A꺼 onClick을 보내주는데, item담아서 보내달라고 하니까 그렇게 써야돼.

3. C : 난 그냥 보내준 onClick 그대로 쓸게.

 

라고 나름 정리를 해봤다..

 

 

여기서 드는 의문들..

 

여기서 엄청 헷갈리는 게 바로 2번이다...

A > B > C로 순차적으로 데이터가 흘러간다 생각했는데, B에서는 오히려 A에게 돌려준다. (아, return느낌으로 받아들이면 되나..?)

음..굳이 표현을 하자면, C에선 B호출 B에선 A호출이라 생각하면 간단한 것도 같은데..

C는 B가 보내준 onClick을 그대로 쓰니까 간단명료..

 

그럼 B도 A가 보내준 걸 그대로 써야지 왜 함수를 호출해서 받은 데이터를 다시 줄까 생각해봤다.

혹시, B는 map을 통해 여러개가 생성되니까 A입장에선 1번데이터인지, 2번데이터인지 구분을 하기 위해 받아온 개별 데이터를 넣어서 호출해주는 건가? 그렇다면 단건을 뿌려주고 받을 때에는 단순 호출만으로 되는건가?


+ 회사에서 codesandbox를 통해 테스트 하면서 확인한 걸 추가로 남겨본다.

codesandbox테스트 보기

 

B에서 onClick={onClick(data)} 와 같은 형태로 사용할 경우 화면이 최초 랜더링 될 때만 콘솔로그 호출이 된다.

원하는 기능이 랜더링 시가 아닌 onClick 이벤트 시 콘솔로그호출이 되어야 하기 때문에 

onClick={() => { onClickItem(items.content);  }} 과 같은 형태로 사용해야 한다. (전에 배웠던게 이제야 떠올랐다..)

 

 

 

그리고 리액트의 흐름이 이해가 되지 않았던 것을 js로 비슷하게 구현해봤다.

const data = {
    "no":1, 
    "startString":"글번호는 ", 
    "endString":"입니다."
};

console.log(MainPage(data)); //📌글번호는 11입니다.

function MainPage(data){ return PostList(data); }

function PostList(data){
 //📌받은 data의 첫문자 + 계산한 no + 끝문자 더해서 반환
 return data.startString + PostListItem(data.no) + data.endString;
}

function PostListItem(no){  return no + 10; }

아침에 문득, 데이터 흐름이 되돌아 간다는 느낌을 받았는데, 

js로 구현해보니 얼추 비슷한 느낌이다. js에서 return느낌으로 받아들이면 될 것 같다.

아직은 리액트 문법이 익숙하지 않기 때문에 그런 흐름이 생소하게 느껴지는것이리라..

 

 

이런 포인트가 몇가지가 있어서 리액트가 어렵다고 느껴지는 거 같은데

계속 생각해서 이해를 하거나, 얜 원래 그런애구나. 하고 익숙해지거나 

암튼 친해지내자 리액트야..

 

궁금증이 담긴 글은 숙제라고 태그 달아놓고, 나중에라도 정리해서 올려야겠다.