민프
[React][TypeScrpit] react-router-dom v6 - Link를 사용하여 화면 간 데이터 이동을 해보자 (state, useLocation()) 본문
[React]
[React][TypeScrpit] react-router-dom v6 - Link를 사용하여 화면 간 데이터 이동을 해보자 (state, useLocation())
민프야 2023. 1. 28. 00:03화면 간 데이터 이동 방법은 앞서 포스팅 한 useParams으로 파라미터 값을 얻어서 할 수도 있고, props로 데이터를 보낼수도 있는데 이번에는 Link를 이용한 데이터 이동을 해보려고 한다.
https://reactrouter.com/en/main/components/link#state
공식문서를 보면
path에 대한 state값을 넣어 상태 저장 값을 설정하고 이 값은 'useLocation()' 으로 받을 수 있다고 나온다. 한번 해보자
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import styled from "styled-components";
const Container = styled.div`
padding: 0px 20px;
max-width: 480px;
margin: 0 auto;
`;
const Header = styled.header`
height:10vh;
display: flex;
justify-content: center;
align-items: center;
`;
const CoinsList = styled.ul``;
const Coin = styled.li`
background-color: white;
color:${props=>props.theme.bgColor};
margin-bottom: 10px;
border-radius: 10px;
cursor: pointer;
a{
padding:20px;
align-items: center;
transition: color 0.1s ease-in;
display: flex;
}
&:hover{
a{
color:${(props)=> props.theme.accentColor}
}
}
`;
const Title = styled.h1`
font-size: 48px;
color:${props => props.theme.accentColor};
`;
const coins = [
{
id: "btc-bitcoin",
name: "Bitcoin",
symbol: "BTC",
rank: 1,
is_new: false,
is_active: true,
type: "coin",
},
{
id: "eth-ethereum",
name: "Ethereum",
symbol: "ETH",
rank: 2,
is_new: false,
is_active: true,
type: "coin",
},
{
id: "hex-hex",
name: "HEX",
symbol: "HEX",
rank: 3,
is_new: false,
is_active: true,
type: "token",
},
]
const Loader = styled.span`
text-align: center;
display: block;
`;
const Img = styled.img`
width: 25px;
height: 25px;
margin-right: 10px;
`;
interface CoinInterface{
id: string,
name: string,
symbol: string,
rank: number,
is_new: boolean,
is_active: boolean,
type: string,
}
function Coins(){
const [coins, setCoins] = useState<CoinInterface[]>([]);
const [loading, setLoading] = useState(true);
useEffect(()=>{
(async()=>{
const response = await fetch("https://api.coinpaprika.com/v1/coins");
const json = await response.json();
setCoins(json.slice(0,100))
setLoading(false);
})();
},[]);
return (
<Container>
<Header>
<Title>코인</Title>
</Header>
{loading ? <Loader>Loading...</Loader>:(
<CoinsList>
{coins.map((coin) =>
(
<Coin key={coin.id}>
<Link to={`/${coin.id}`} state={coin.name}>
<Img src={`https://coinicons-api.vercel.app/api/icon/${coin.symbol.toLocaleLowerCase()}`}/>
{coin.name} →
</Link>
</Coin>)
)
}
</CoinsList>
)}
</Container>
);
}
export default Coins;
import { useLocation, useParams } from "react-router-dom";
import styled from "styled-components";
const Title = styled.h1`
color:${props => props.theme.accentColor};
`;
function Coin(){
//파라미터 값 가져오기
const { coinId } = useParams();
//state 값 가져오기
const location = useLocation();
console.log(location)
return <Title>Coin: {coinId}</Title>
}
export default Coin;
Link state로 정보를 보내주고 useLocation() 으로 정보를 받아와서 log를 찍어보니 잘 적용된 것을 확인할 수 있었다.
useLocation()에서 type을 지정하고 state만 따로 보고싶으면 interface로 type을 지정해줘야한다.
import { useLocation, useParams } from "react-router-dom";
import styled from "styled-components";
const Title = styled.h1`
color:${props => props.theme.accentColor};
`;
interface RouteState{
name:string;
}
function Coin(){
//파라미터 값 가져오기
const { coinId } = useParams();
//state 값 가져오기
const location = useLocation();
const name = location.state as RouteState;
console.log(name)
return <Title>Coin: {coinId}</Title>
}
export default Coin;
interface를 지정해주고 useLocation()으로 가져온 값에다 적용해주면 된다.
이렇게 되면 꼭 이전 페이지에서 클릭 후 state를 보내줘야만 접근이 가능하다
따라서 이 부분도 필요한 부분에 잘 사용하면 이전 페이지에서 받은 정보로 다음페이지를 구현할 수도 있을 것 같다.
'[React]' 카테고리의 다른 글
Comments