페이지 새로 고침 시 NextJS에서 Redex 상태를 올바르게 수산화하는 방법
앱 다시 로드/페이지 새로 고침 시 로컬 스토리지에서 사용자 데이터에 수분이 공급되는 문제가 발생함.
내 프로젝트에서 프런트엔드와 지원 라이브러리에 NextJS를 사용하고 있다.redux-toolkit
애플리케이션 전체에서 환원 관리를 위해next-redux-wrapper
포장된 페이지들에 대한 국가수화를 위해.
사용자가 로그인할 수 있으며, 이 경우 다음 항목을 저장한다.isLoggedIn
로컬 저장소와 환원 상태의 부울.에 따라isLoggedIn
부울 값 I 변경Navbar
구성요소 스타일(더)Navbar
에 직접 포함되다_app.tsx
).
사용자가 페이지를 새로 고칠 때isLoggedIn
부울은 상태로 로드되지 않고 로컬 저장소에 있다.
과거에 나는 사용해 왔다.redux-persist
하지만 나는 그것을 사용하지 않기로 선택했다. 왜냐하면 그 이유는PersistGate
SSR 아이디어와 충돌하는 저장소에서 지속 데이터를 가져올 때까지 UI 렌더링을 차단하고 있었다.
현재, 나는 다음 것을 가지고 있다.isLoggedIn
로딩 문제 해결 방법App.getInitialProps
에 있어서의 방법._app.ts
그리고 나서 그 결과 로부터 수분을 공급하게 된다.next-redux-persist
로드된 각 페이지와 모든 페이지에 대해 호출되지만, 이것은 또 다른 문제를 야기한다: 모든 페이지는 현재 서버 측에서 렌더링되고 NextJS의 정적 페이지 최적화는 없다.
NextJS에서 정적 페이지 최적화를 잃지 않고 사용하지 않을 수 있는 방법이 있는가?redux-persist
그리고 어떤 페이지가 새로 고쳐졌을 때 여전히 클라이언트측 스토어에 수분을 공급할 수 있는가?
현재 코드 구조(간편성을 위해 일부 코드가 생략됨):
file: _app.tsx
import { wrapper } from 'store';
const MyApp = ({ Component, pageProps }: AppProps) => {
return (
<>
<Navbar />
<Component {...pageProps} />
</>
);
};
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
return { ...appProps };
};
export default wrapper.withRedux(MyApp);
file: store.ts
import {
combineReducers,
configureStore,
EnhancedStore,
getDefaultMiddleware
} from '@reduxjs/toolkit';
import { createWrapper, MakeStore } from 'next-redux-wrapper';
import userReducer from 'lib/slices/userSlice';
const rootReducer = combineReducers({
user: userReducer
});
const setupStore = (context): EnhancedStore => {
const middleware = [...getDefaultMiddleware(), thunkMiddleware];
if (process.env.NODE_ENV === 'development') {
middleware.push(logger);
}
return configureStore({
reducer: rootReducer,
middleware,
// preloadedState,
devTools: process.env.NODE_ENV === 'development'
});
};
const makeStore: MakeStore = (context) => setupStore(context);
export const wrapper = createWrapper(makeStore, {
debug: process.env.NODE_ENV === 'development'
});
file: userSlice.ts
import { createSlice } from '@reduxjs/toolkit';
import { HYDRATE } from 'next-redux-wrapper';
const initialState = {
isLoggedIn: false
}
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
login: (state) => {
state.isLoggedIn = true;
localStorage.setItem('loggedInData', { isLoggedIn: true });
}
},
extraReducers: (builder) => {
builder
.addCase(HYDRATE, (state, action: any) => {
if (typeof window !== 'undefined') {
const storedLoggedInData = localStorage.getItem('loggedInData');
if (storedLoggedInData != null && storedLoggedInData) {
const parsedJson = JSON.parse(storedLoggedInData);
state.isLoggedIn = parsedJson.isLoggedIn ?? false;
} else {
state.isLoggedIn = false
}
}
});
}
});
export const isLoggedInSelector = (state: RootState) => state.user.isLoggedIn;
export default userSlice.reducer;
file: Navbar.tsx
import { useSelector } from 'react-redux';
import { isLoggedInSelector } from 'lib/slices/userSlice';
export default function Navbar() {
const isLoggedIn = useSelector(isLoggedInSelector);
return (
<div className={`${ isLoggedIn ? 'logged-in-style' : 'logged-out-style'}`}>...</div>
)
}
오늘도 같은 이슈였다.문제는 페이지 렌더링에서 클라이언트 스토리지를 분리하여 로 이동시켜야 한다는 것이다.useEffect
구성 요소가 장착되는 위치.기본 아이디어는 먼저 페이지를 완전히 렌더링한 다음 클라이언트 저장소 정보를 사용하여 페이지를 업데이트하십시오.
고객의 로컬 스토리지를 직접 통합하면 수화작용을 방해할 수 있다.
여기 내가 사용하는 코드 샘플이 있다.
export default const MenuBar = () => {
const isLoggedIn = useSelector((state) => state.isLoggedIn);
useEffect(() => {
// loads from clients local storage
const auth = loadAuthenticationToken();
if (auth !== null) {
// updates the store with local storage data
dispatch(actions.jwtTokenUpdate(auth));
}
}, [dispatch]);
if (isLoggedIn) {
return <p>you are logged in</p>;
} else {
return <p>please log in</p>;
}
}
참고로 NextJS에 대한 github 이슈: https://github.com/vercel/next.js/discussions/17443
렌더링을 위해 창 액세스가 필요한 블로그 게시물: https://dev.to/adrien/creating-a-custom-react-hook-to-get-the-window-s-dimensions-in-next-js-135k
_app.js에서 getInitialProps를 사용하면 정적 최적화가 손실된다는 것이 문서에 언급되어 있다.서버 쪽에서는 왜 Redex를 사용하는지 모르겠는데, 개인적으로 클라이언트 쪽에서만 사용하라고 조언할 것이고, 후드 아래에서는 getInitialProps를 사용하기 때문에 더 이상 next-remex-wrapper를 사용하지 않아도 될 것이다.
또한 next-remensx-wrapper는 app.js/ts에서 getInitialProps를 스토어로 포장할 때 사용한다.그래서 당신이 이 라이브러리를 사용하고 그것으로 당신의 앱을 포장하면 당신은 자동적으로 정적 최적화를 잃게 된다.
'programing' 카테고리의 다른 글
npm 패키지의 덮어쓰기 유형 정의 (0) | 2022.04.03 |
---|---|
Vue 프로젝트의 보기와 구성 요소 폴더 간의 차이점은? (0) | 2022.04.03 |
iOS 및 Android용 Resact Native 응용 프로그램에서 인터넷 연결을 확인하는 방법 (0) | 2022.04.03 |
vue 라우팅: 올바른 라우팅/프로토콜이 있는 동일한 페이지의 목록-프로토콜 보기 (0) | 2022.04.03 |
python에서 float를 정수로 변환하는 가장 안전한 방법? (0) | 2022.04.03 |