본문 바로가기
부트캠프 개발일지 2023-2024/Bootcamp 생활기록

[7주차] 리액트: Link 에서 데이터 전달하기 (useLocation)

by whereanna00 2023. 11. 15.

이전 포스트

 

[7주차] 리액트: json의 id 값에 따라 상세페이지로 이동하기 (useParams, Link)

리액트 json의 id 값에 따라 상세페이지로 이동하기 (useParams, Link) Router.js 새 Route 를 만들어주고, path="" 와 element={} 를 넣어준다 id 값에 따라서 다른 상세화면을 보여주고 싶으면, path=""상세페이지

whereannalee.tistory.com

 

 

리액트 Link 에서 데이터 전달하기

json 으로 구성된 dummy data 에서 id 값에 따른 상세페이지 이동까지 구현한 후, 이제 클릭된 id 를 포함하는 객체(letter 하나)에서 그 외 더 다양한 정보를 상세페이지에 전달해야 한다.

 

일단 초기 상태는 아래와 같다.

 

(1) 초기 상태 코드

id 값은 이미 useParams 을 통해 상세페이지에 전달되었으므로 LetterDetails의 리턴부분 jsx 영역에 {id} 를 넣으면, 화면에 id 값이 랜더링된다.

 

 

List.jsx

더보기
import React from 'react'
import {styled} from "styled-components";
import uuid from 'react-uuid';
import userIcon from '../assets/user-icon.png';
import { Link, useParams } from 'react-router-dom';


const ListArea = styled.div`
  border: 1px solid black;
  width: 450px;
  height: 400px;
  margin: 50px 25px 50px 25px;
  overflow-y: scroll;
`;

const Letter = styled(Link)`
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  color: black;
  background-color: #e9e9e9;
  margin: 20px;
  padding: 10px;
  gap: 5px;
  height: 180px;
  cursor: pointer;
  text-decoration: none;
  transition: 0.3s ease;
  &:hover {
    transform: scale(1.02);
    background-color: #acacac;
  }
`;

const Message = styled.span`
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;  
`;

const UserIcon = styled.img`
  align-self: start;
  margin: 20px;
  width: 50px;
`;

function List({letters, setLetters}) {
  return (
    <ListArea>
      {letters.map((letter)=>{
        return(
          <Letter
            key={uuid()}
            to={`/letter-details/${letter.id}`}
           >
            <UserIcon src={userIcon} alt="User Icon"/>
            <div>
              <h3>{letter.userName}</h3>
              <p>{letter.createdAt}</p>
              <span>To...{letter.wroteTo},&nbsp;</span>
              <Message>{letter.message}</Message>
              <p>{uuid()}</p>
            </div>
          </Letter>
        );
      })}
    </ListArea>
  )
}

export default List

 

LetterDetails.jsx

더보기
import React from 'react'
import { useParams } from 'react-router-dom';


function LetterDetails({}) {

  const { id } = useParams();

  return (
    <div>
      <div>
        letter details~
        <p>id: {id}</p>
      </div>
    </div>
  );
}

export default LetterDetails

 

 

(2) List.jsx(정보를 보내는) 에서 작업할 것

현재 <Letter>의 속성으로 key와 to가 들어있는데, 데이터를 넘겨주려면 state 속성을 추가한다.

state={}

 

그 안에는 넘겨줄 데이터들을 객체의 형태로 넣어준다. 아마 state가 객체형태로 전달되기 때문인 것 같다.

더보기

** 현재 <Letter> 부분은 map으로 돌려져서 리턴값으로 나오는 부분이기 때문에, map의 parameter인 letter.~ 로 접근해야 한다. 따라서 지정하고싶은 변수이름 : letter.userName 처럼 state(객체형태)의 key와 value 값을 넣어준다.

import React from 'react'
import {styled} from "styled-components";
import uuid from 'react-uuid';
import userIcon from '../assets/user-icon.png';
import { Link, useParams } from 'react-router-dom';


const ListArea = styled.div`
  border: 1px solid black;
  width: 450px;
  height: 400px;
  margin: 50px 25px 50px 25px;
  overflow-y: scroll;
`;

const Letter = styled(Link)`
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  color: black;
  background-color: #e9e9e9;
  margin: 20px;
  padding: 10px;
  gap: 5px;
  height: 180px;
  cursor: pointer;
  text-decoration: none;
  transition: 0.3s ease;
  &:hover {
    transform: scale(1.02);
    background-color: #acacac;
  }
`;

const Message = styled.span`
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;  
`;

const UserIcon = styled.img`
  align-self: start;
  margin: 20px;
  width: 50px;
`;

function List({letters, setLetters}) {
  return (
    <ListArea>
      {letters.map((letter)=>{
        return(
          <Letter
            key={uuid()}
            to={`/letter-details/${letter.id}`}
            state={{userName : letter.userName
            , createdAt : letter.createdAt
            , wroteTo : letter.wroteTo
            , message : letter.message
            }}>
            <UserIcon src={userIcon} alt="User Icon"/>
            <div>
              <h3>{letter.userName}</h3>
              <p>{letter.createdAt}</p>
              <span>To...{letter.wroteTo},&nbsp;</span>
              <Message>{letter.message}</Message>
              <p>{uuid()}</p>
            </div>
          </Letter>
        );
      })}
    </ListArea>
  )
}

export default List

 

 

 

 

(3) LetterDetails.jsx (정보를 받는) 에서 작업할 것

정보를 받으려면 useLocation 을 통해 받아야 한다.

 

먼저 useLocation 을 import 한다.

import { useLocation } from 'react-router-dom';

 

 

그 다음, useLocation 을 선언해준다. LetterDetails 안에!

  const location = useLocation();

 

 

location.state.key이름 (location을 통해 state라는 객체의 key 에 접근한다는 뜻)을 새로운 변수에 할당한다.

  // 이전 작업
  const location = useLocation();
  
  // 추가한 작업
  const userName = location.state.userName;
  const userCreatedAt = location.state.createdAt;
  const wroteTo = location.state.wroteTo;
  const message = location.state.message;

 

 

 

이제 LetterDetails의 반환값에서 호출해준다.

  return (
    <div>
      <div>
        letter details~
        <p>username: {userName}</p>
        <p>date: {userCreatedAt}</p>
        <p>To... {wroteTo}</p>
        <p>message: {message}</p>
        <p>id: {id}</p>
      </div>
    </div>
  );

 

 

 

 

(4) 완성된 코드

List.jsx

더보기
import React from 'react'
import {styled} from "styled-components";
import uuid from 'react-uuid';
import userIcon from '../assets/user-icon.png';
import { Link, useParams } from 'react-router-dom';


const ListArea = styled.div`
  border: 1px solid black;
  width: 450px;
  height: 400px;
  margin: 50px 25px 50px 25px;
  overflow-y: scroll;
`;

const Letter = styled(Link)`
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  color: black;
  background-color: #e9e9e9;
  margin: 20px;
  padding: 10px;
  gap: 5px;
  height: 180px;
  cursor: pointer;
  text-decoration: none;
  transition: 0.3s ease;
  &:hover {
    transform: scale(1.02);
    background-color: #acacac;
  }
`;

const Message = styled.span`
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;  
`;

const UserIcon = styled.img`
  align-self: start;
  margin: 20px;
  width: 50px;
`;

function List({letters, setLetters}) {
  return (
    <ListArea>
      {letters.map((letter)=>{
        return(
          <Letter
            key={uuid()}
            to={`/letter-details/${letter.id}`}
            state={{userName : letter.userName
            , createdAt : letter.createdAt
            , wroteTo : letter.wroteTo
            , message : letter.message
            }}>
            <UserIcon src={userIcon} alt="User Icon"/>
            <div>
              <h3>{letter.userName}</h3>
              <p>{letter.createdAt}</p>
              <span>To...{letter.wroteTo},&nbsp;</span>
              <Message>{letter.message}</Message>
              <p>{uuid()}</p>
            </div>
          </Letter>
        );
      })}
    </ListArea>
  )
}

export default List

 

 

LetterDetails.jsx

더보기
import React from 'react'
import { useParams, useLocation } from 'react-router-dom';


function LetterDetails({}) {

  const { id } = useParams();
  const location = useLocation();
  const userName = location.state.userName;
  const userCreatedAt = location.state.createdAt;
  const wroteTo = location.state.wroteTo;
  const message = location.state.message;

  return (
    <div>
      <div>
        letter details~
        <p>username: {userName}</p>
        <p>date: {userCreatedAt}</p>
        <p>To... {wroteTo}</p>
        <p>message: {message}</p>
        <p>id: {id}</p>
      </div>
    </div>
  );
}

export default LetterDetails

 

화면

 


참고

 

[웹1팀] [React] Link를 통해 props를 전달하는 방법

게시판의 Update 기능을 구현하던 도중, 수정 버튼을 누르면 게시글 수정 페이지로 이동하면서 작성 폼에 내가 수정하려는 글이 입력되어 있었으면 좋겠다는 생각이 들었다. 그러면 어떻게 내가

dsc-sookmyung.tistory.com

 

React Router를 이용하여 component간에 props 넘겨주기

*https://medium.com/@ghur2002/react-router%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-component%EA%B0%84%EC%97%90-props-%EB%84%98%EA%B2%A8%EC%A3%BC%EA%B8%B0-610de3511c67를 참고하였습니다. 1. match.params 값으로 데이터 넘기기 component

digital-detox.tistory.com

 

[React] Link로 데이터 전달하기

프로젝트를 진행하며Link로 페이지를 이동하고 데이터도 함께 전달해야 할 경우에 recoil을 사용해서 값을 전달해도 되지만, props처럼 값을 바로 넘기는 방법에 대해서도 확인해 봤습니다.아래와

velog.io

 

728x90
반응형