본문 바로가기

TIL/React

(7)
useState(useRecoilState)를 동기적으로 처리하는 방법 문제 상황 아래와 같은 코드를 통해 (1)로그인 성공 → (2)setIsLogin 함수 실행(isLogin = true) → (3)navigate 함수 실행 의 순서로 진행되는 로직을 구현하려 했다. ... const [isLogin, setIsLogin] = useRecoilState(isLoginState); const getToken = async () => { await axios({ method: "GET", url: `${process.env.REACT_APP_BASE_URL}/auth/kakao/callback`, params: { authCode, }, withCredentials: true, }) .then((res) => { // (1) 로그인 성공 onLoginSuccess(res)...
React.StrictMode로 인한 KOE320 에러 (카카오 로그인) 문제상황 새로운 서비스의 카카오 로그인 기능을 구현하던 중, 인가 코드를 통해 카카오 서버로부터 액세스 토큰을 받아오는 과정에서 다음과 같이 KOE320 에러가 발생했다. KOE320에 대해 검색해보니, 이미 발급된 인가코드를 다시 사용하여 발생하는 문제라고 한다. 현재 로그인 관련 로직은 다음과 같이 구현되어 있다. 카카오 계정으로 로그인 카카오 콜백 url(클라이언트측으로 설정)에서 인가코드를 받아오고, 이를 담아 서버측으로 API 요청 서버 API에서 인가코드를 통해 액세스 토큰을 받아온 후 회원가입or로그인 처리 클라이언트로 액세스 토큰 response body에 담아서 보냄 & refresh token은 httpOnly 쿠키에 저장 클라이언트에서 토큰 받아와서 axios.defaults.head..
React) 백엔드와 연동하여 좋아요 기능 구현하기 <TIL_2022_07_31> 위 그림과 같이 각 게시글마다 좋아요를 누를 수 있게 하는 기능을 구현하고자 한다. Likes 테이블 생성, 관계 설정 한 명의 유저가 여러 개의 게시글에 좋아요를 누를 수 있고, 한 개의 게시글에도 마찬가지로 여러명의 좋아요가 기록될 수 있으므로, user와 questions 테이블은 서로 N : M(다 대 다) 관계를 갖는다. 이들을 이어줄 인자값으로 likes 테이블을 생성한다. // models/likes.js const Sequelize = require("sequelize"); module.exports = function (sequelize, DataTypes) { return sequelize.define( "likes", { id: { type: DataTypes.INTEGER, allo..
React) <Outlet/>의 context를 이용하여 중첩 라우터에 props 넘겨주기 <TIL_2022_07_28> 위와 같은 라우팅 구조에서, 부모 컴포넌트로부터 자식 컴포넌트로 넘기고 싶은 값이 있다면 context props로 넘기면 된다. // 부모 컴포넌트 ... ... 자식 컴포넌트에서 받아올 때는 useOutletContext라는 훅을 사용한다. //자식 컴포넌트 // 구조분해할당. const user = useOutletContext().user 와 같은 뜻. const { user } = useOutletContext();
React) Recoil - 페이지 이동 시 비동기 데이터를 state로 넘긴 후 redirect될때 state값이 사라져서 발생하는 에러 해결 (selectorFamily) <TIL_2022_07_27> 특정 유저에게 아래와 같이 질문 내용을 전달하는 기능을 구현하고자 하였다. 서버로 POST 요청을 보냈더니 아래와 같은 에러가 뜬다 POST 요청은 정상적으로 처리되었다. 그렇다면 프론트엔드 코드의 문제인데, 콘솔창을 뜯어본 결과 POST 요청 후 리디렉팅될때 이전 라우팅 경로에서 전달 받은 state 값이 사라지는 현상이 발생해서 에러가 뜬 것이었다. 해결방안 Recoil을 사용하여 비동기로 받아온 유저 정보를 전역상태로 관리하는 방법으로 해결. API에 파라미터를 전달할 필요가 없는 경우 다음과 같이 selector를 사용하여 비동기 데이터를 전역상태로 관리하고 사용하였다. // atoms.js export const userInfoSelector = selector({ key: "userInfoSe..
React) Recoil - recoilPersist, selector <TIL_2022_07_26> recoilPersist() https://velog.io/@tamagoyakii/42byte-Recoil%EB%A1%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0 페이지가 변경되더라도 상태관리를 유지하기 위해 생성 로그인 상태 관리할때, export const isLoggedIn = atom({ key: `isLoggedIn${v1}`, default: false, }); 이렇게 atom 형태로 저장해서 사용하면 컴포넌트가 전환될때 새로고침하면 값 보존이 안된다. const { persistAtom } = recoilPersist(); export const LoginState = atom({ ..
React) 객체 형태로 여러개의 state 관리하기 <TIL_2022_07_25> 프로필 정보 수정 - 객체 형태로 여러개의 state 관리하기 이렇게 총 네가지 항목의 값을 수정하는 기능을 구현해야 하는 경우, onChangeNickname, onChangeJob, … 이렇게 onChange와 useState를 변수마다 각각 지정하여 사용하는 방법도 있지만 최선은 아니다. (코드도 더 길어지고, 메모리 측면에서도 비효율적인 것 같다. 자세한 원리까지는 아직 잘 모르겠다) 가장 좋은 방법은 각 태그에 name 속성을 지정하여 이벤트가 발생했을때 그 값을 참조하는 것. useState로 문자열이나 배열 뿐만 아니라 객체 형태도 관리할 수 있다. // user는 DB에서 받아온 유저 정보 객체 const [userInputs, setUserInputs] = useState({ nickna..