지난 포스팅에서 로그인, 로그아웃까지 만들었다.
이번엔 로그인한 상태에서 댓글을 달면 좌측에 리스트에 추가 시켜볼 것이다.
댓글 리스트 불러오기
먼저 data.json 파일에 리뷰 리스트에 해당되는 데이터 배열을 추가한다.
"review": [
{
"memName": "김철수",
"memId": "kim1234",
"day": "2024-05-32",
"content": "잘 보고 갑니다.",
"id": "6082"
},
{
"memName": "홍길동",
"memId": "hong1234",
"day": "2024-05-32",
"content": "항상 행복하세요.",
"id": "5004"
}
]
로컬에서 본 데이터와 작성한 코드
이제 이 데이터를 불러와서 댓글 리스트에 추가해준다.
이전에 만들어두었던 useFetch를 사용하여 데이터를 얻어온다.(GET)
import useFetch from '../hooks/useFetch'
export default function ReviewList(){
const item = useFetch('http://localhost:3001/review');
return(
<div className="reviewList">
<ul>
{item.map((it)=>(
<li key={it.id}>
<p className="reviewName">
<span>{it.memName} 님</span>
<span>2024-05-32</span>
</p>
<p className="reviewContents">{it.content}</p>
</li>
))}
</ul>
</div>
)
}
처음에 이런식으로 코드를 넣었더니 TypeError: item.map is not a function 오류가 생겼다.
위에 오류는 보통 item이 Array(배열) 타입이 아닐 때 나오는 오류인데,
console.log(item)을 넣어보니 아래처럼 Object 타입으로 들어가있었다.
저 데이터 중에서 data를 가져와야하기 때문에 item.data.map()으로 써줘야했다.
그리고 data 배열이 존재할 때만 적용이 가능하도록 item.data?map()으로 작성해줘야 한다.
fetch를 사용할 때는 data를 추가로 쓰지 않아도 됐는데, axios는 필요한 부분까지 적는것에 익숙해져야할 것 같다.
import useFetch from '../hooks/useFetch'
export default function ReviewList(){
const item = useFetch('http://localhost:3001/review');
return(
<div className="reviewList">
<ul>
{item.data?.map((it)=>(
<li key={it.id}>
<p className="reviewName">
<span>{it.memName} 님</span>
<span>{it.day}</span>
</p>
<p className="reviewContents">{it.content}</p>
</li>
))}
</ul>
</div>
)
}
최종적으로 위에 코드처럼 적용을 해주니 정상적으로 댓글 리스트에 적용됐다.
LocalStorage로 로컬에 데이터 저장하기
"review": [
{
"memName": "김철수",
"memId": "kim1234",
"day": "2024-05-30",
"content": "잘 보고 갑니다.",
"id": "6082"
},
{
"memName": "홍길동",
"memId": "hong1234",
"day": "2024-05-20",
"content": "항상 행복하세요.",
"id": "5004"
}
]
review 데이터들을 보면 내가 "memId"를 추가한 것이 보인다.
누가 댓글을 썼는지 확인할 수 있도록, 그리고 내가 쓴 댓글이면 지우거나 수정할 수 있도록 하기 위해서 추가해뒀다.
그럼 로그인 한 사용자(나)의 memId값을 어떻게 받아와야 할까?
나는 여기서 LocalStorage를 사용하여 로컬에 memId 를 저장하고, 댓글의 memId와 일치한다면 삭제를 할 수 있도록 할 것이다.
로컬스토리지 사용법
// 데이터 저장하기
localStorage.setItem("key", value);
// 데이터 읽기
localStorage.getItem("key");
// 데이터 삭제
localStorage.removeItem("key");
// 모든 데이터 삭제
localStorage.clear();
// 저장된 키/값 쌍의 개수
localStorage.length;
💡로컬스토리지는 탭끼리 데이터를 공유할 수 있고, 일정 기간이 지나야 지워진다.
따라서 탭을 이동하거나 닫아도 데이터가 유지될 수 있다.
데이터를 저장하려면 먼저 로그인할 때부터 저장이 돼야해서 다시 LogIn.js를 수정했다.
(...)
function onSubmit(){
axios.post('http://localhost:3001/members',{id, pw})
.then((res)=>{
const result = item.data.find((item)=> item.memId === id && item.memPw === pw);
if(result){
navigate('/')
LogInFunc(true);
localStorage.setItem("memId", JSON.stringify(res.data));
const memInfo = JSON.parse(localStorage.getItem("memId"));
console.log(memInfo.id);
}else{
(...)
💡 객체 형식인 localstorage를 배열로 저장해야한다면 JSON.stringify()로 감싸준다.
불러올 때는 다시 객체 형식으로 불러오기 위해서 JSON.parse()로 감싸줘야한다.
이대로 로그인을 다시 해보면
이제 JSON.parse(localStorage.getItem("memInfo")) 를 어떤 컴포넌트에서 사용해도 정보를 내 로컬에서 불러올 수 있다.
나는 id와 동일한 정보를 가진 전체 데이터를 불러올 예정이다.
(...)
function onSubmit(){
axios.post('http://localhost:3001/members',{id, pw})
.then((res)=>{
const result = item.data.find((item)=> item.memId === id && item.memPw === pw);
if(result){
navigate('/')
LogInFunc(true);
const memInfo = item.data.filter((it)=> it.memId === id );
localStorage.setItem("memInfo", JSON.stringify(memInfo));
(...)
위와 같이 filter 메서드를 사용하면 로그인이 성공했을 때, id와 동일한 값을 가진 데이터를 필터링하여 로컬스토리지에 저장할 수 있다.
누구나 볼 수 있는 나의 로컬스토리지에 비밀번호 및 개인정보가 다 보이는건 불안하다.
찾아보니 데이터를 암호화 시켜주는 React Secure Storage 라이브러리가 있었다.
조금이나마 보안을 해결할 수 있도록 해당 라이브러리를 사용해준다.
React Secure Storage 사용법
사용방법은 간단하다.
라이브러리를 설치해준다.
npm i react-secure-storage
import로 불러온다.
import secureLocalStorage from "react-secure-storage";
localstorage로 작성한 부분을 secureLocalStorage로 바꿔주고 stringify도 없애준다.
(객체 형식인 localstorage와 다르게 secureLocalStorage는 문자열, 객체, 숫자, 불리언 값 형식이다.)
(...)
function onSubmit(){
axios.post('http://localhost:3001/members',{id, pw})
.then((res)=>{
const result = item.data.find((item)=> item.memId === id && item.memPw === pw);
if(result){
navigate('/')
LogInFunc(true);
const memInfo = item.data.filter((it)=> it.memId === id );
secureLocalStorage.setItem("memInfo", memInfo );
(...)
여기서 만약 memId값만 가져오고 싶다면
const memmem = secureLocalStorage.getItem("memInfo")
console.log(memmem[0].memId)
위의 코드를 사용해서 불러올 수 있다. (엄청난 시행착오가 있었다.)
위처럼 코드를 적고 데이터를 불러올 때, 암호화된 값이 아닌 원래의 값으로 복호화되어 나온다면 정상적으로 작동한 것이다.
이제 다음 포스팅에선 댓글을 작성하여 리스트에 추가하는 것을 해볼 것이다.
'Study > React' 카테고리의 다른 글
[React] styled-components로 다크모드 만들기 (placeholder, after, before...) (0) | 2024.07.12 |
---|---|
[React] styled-components로 다크모드 만들기(ThemeProvider/useContext) (0) | 2024.07.10 |
[ReactJS/AXIOS] 백엔드 없이 로그인 구현하기 (4) (0) | 2024.07.04 |
[ReactJS/AXIOS] 백엔드 없이 로그인 구현하기 (2)_DELETE (0) | 2024.07.01 |
[ReactJS/AXIOS] 백엔드 없이 로그인 구현하기_GET, POST (0) | 2024.07.01 |