Redux 工具包存储在下一个 js 中的页面之间导航时自动重置
Redux toolkit store reset automatically in navigating between pages in next js
我是 Next 的新用户,长期以来一直在使用 Redux 和 React
我在将 Redux 与 Next
一起使用时遇到了很多麻烦
我已完成此解决方案
store.js
import { configureStore } from '@reduxjs/toolkit';
import reducers from './rootReducer';
export function makeStore() {
return configureStore({
reducer: reducers,
});
}
const store = makeStore();
export default store;
rootReducer.js
import { combineReducers } from '@reduxjs/toolkit';
import tes from './test/tes';
const reducers = combineReducers({
test: tes,
});
export default reducers;
_app.js
import React from 'react';
import { Provider } from 'react-redux';
import store from '../redux/store';
import { createWrapper } from 'next-redux-wrapper';
const MyApp = ({ Component, ...rest }) => {
return (
<Provider store={store}>
<Component {...rest} />
</Provider>
);
};
const makestore = () => store;
const wrapper = createWrapper(makestore);
export default wrapper.withRedux(MyApp);
但是我发现任何使用useDispatch
在任何页面里面,搜索引擎在抓取数据后不识别页面内容
import React, { useEffect } from 'react';
import { Test } from '../../redux/test/tes';
import { useDispatch, useSelector } from 'react-redux';
import Link from 'next/link';
function TestPage() {
const dispatch = useDispatch();
const { data } = useSelector((state) => state.test);
useEffect(() => {
dispatch(Test('hi'));
}, []);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data.map((name) => (
<h1>{name.title}</h1>
))}
</div>
);
}
export default TestPage;
必须使用以下预渲染方法之一
我想知道下一个是否正常
或者有更好的方法吗?
#1 更新
现在将数据提取移动到 getStaticProps
TestPage.js
import React from 'react';
import { Test } from '../../redux/test/tes';
import { useSelector } from 'react-redux';
import Link from 'next/link';
import { wrapper } from '../../redux/store';
function TestPage({ pageProps }) {
const { data } = useSelector((state) => state.test);
console.log(data);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data && data.map((name) => (
<h1>{name.name}</h1>
))}
</div>
);
}
export const getStaticProps = wrapper.getStaticProps(
(store) => async (context) => {
const loading = store.getState().test.loading;
if (loading === 'idle') {
await store.dispatch(Test('hi'));
}
return {
props: { },
};
}
);
export default TestPage;
现在的问题是商店没有更新
useSelector return []
虽然 console.log (data)
来自 getStaticProps 的数据存在
__NEXT_REDUX_WRAPPER_HYDRATE__
我卡住了
#2更新
到达这里真的很难,在那之后,使用 Next js 获取 Redux 仍然存在问题
现在一切正常,直到导航到任何页面 getStaticProps
或 getServerProps
状态自动重置
store.js
import reducers from './rootReducer';
import { configureStore } from '@reduxjs/toolkit';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
const reducer = (state, action) => {
if (action.type === HYDRATE) {
let nextState = {
...state,
...action.payload,
};
return nextState;
} else {
return reducers(state, action);
}
};
const isDev = process.env.NODE_ENV === 'development';
const makeStore = (context) => {
let middleware = [];
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(middleware),
devTools: isDev,
preloadedState: undefined,
});
return store;
};
export const wrapper = createWrapper(makeStore, { debug: isDev });
1.) Does using Redux with Nextjs eliminate the SEO advantage?
不,将 Redux 与 NextJs 一起使用不会妨碍 SEO 优势。 Redux 与 NextJS 配合得很好。
问题在于您对数据获取的实现。 NextJS 看不到获取的内容,因为您需要在 getInitialProps
、getServerSideProps
或 getStaticProps
中获取它,具体取决于您希望应用程序的工作方式。
请参阅 NextJS 的 Data Fetching documentation。
请注意,getServerSideProps
和 getStaticProps
是处理数据获取的推荐方法。
如果您选择 getStaticProps
,则需要 getStaticPaths
。检查此答案以查看用例和 ,因为它可能令人困惑。
TLDR;不要将数据获取放在 useEffect 挂钩中,而是将其移动到 getServerSideProps
或 getStaticProps
函数中。
最后只用这个方法
即使服务器和客户端状态分离也不起作用
rootReducer.js
const rootReducer = createReducer(
combinedReducers(undefined, { type: '' }),
(builder) => {
builder
.addCase(HYDRATE, (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff = stateDiff?.test?.data?.[0];
const isdiff1 =
stateDiff?.test1?.data?.[0]
return {
...state,
...action.payload,
test: isdiff ? action.payload.test : state.test,
test1: isdiff1 ? action.payload.test1 : state.test1,
};
})
.addDefaultCase(combinedReducers);
}
);
这里唯一的问题是你必须测试状态中每一块的每一个变化
最佳答案留到悬赏结束,谢谢大家
更新:
因为全球水合物还原剂可能会矫枉过正。
这是一个处理每个切片中水合作用的示例
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { diff } from 'jsondiffpatch';
import { HYDRATE } from 'next-redux-wrapper';
const initialState = {
data: [],
};
export const TestFetch = createAsyncThunk(
'TestFetch',
async (data, { rejectWithValue, dispatch }) => {
try {
const response = await fetch(
'https://jsonplaceholder.typicode.com/users'
);
const d = await response.json();
return d;
} catch (error) {
return rejectWithValue(error.response.data.error);
}
}
);
const test = createSlice({
name: 'test',
initialState,
reducers: {
update: {
reducer: (state, { payload }) => {
return { ...state, data: payload };
},
},
},
extraReducers: {
[HYDRATE]: (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff1 = stateDiff?.server?.[0]?.test?.data?.[0];
// return {
// ...state,
// data: isdiff1 ? action.payload.server.test.data : state.data,
// };
state.data = isdiff1 ? action.payload.server.test.data : state.data;
},
[TestFetch.fulfilled]: (state, action) => {
state.data = action.payload;
},
},
});
export const { update } = test.actions;
export default test.reducer;
我是 Next 的新用户,长期以来一直在使用 Redux 和 React 我在将 Redux 与 Next
一起使用时遇到了很多麻烦我已完成此解决方案
store.js
import { configureStore } from '@reduxjs/toolkit';
import reducers from './rootReducer';
export function makeStore() {
return configureStore({
reducer: reducers,
});
}
const store = makeStore();
export default store;
rootReducer.js
import { combineReducers } from '@reduxjs/toolkit';
import tes from './test/tes';
const reducers = combineReducers({
test: tes,
});
export default reducers;
_app.js
import React from 'react';
import { Provider } from 'react-redux';
import store from '../redux/store';
import { createWrapper } from 'next-redux-wrapper';
const MyApp = ({ Component, ...rest }) => {
return (
<Provider store={store}>
<Component {...rest} />
</Provider>
);
};
const makestore = () => store;
const wrapper = createWrapper(makestore);
export default wrapper.withRedux(MyApp);
但是我发现任何使用useDispatch 在任何页面里面,搜索引擎在抓取数据后不识别页面内容
import React, { useEffect } from 'react';
import { Test } from '../../redux/test/tes';
import { useDispatch, useSelector } from 'react-redux';
import Link from 'next/link';
function TestPage() {
const dispatch = useDispatch();
const { data } = useSelector((state) => state.test);
useEffect(() => {
dispatch(Test('hi'));
}, []);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data.map((name) => (
<h1>{name.title}</h1>
))}
</div>
);
}
export default TestPage;
必须使用以下预渲染方法之一
我想知道下一个是否正常
或者有更好的方法吗?
#1 更新
现在将数据提取移动到 getStaticProps
TestPage.js
import React from 'react';
import { Test } from '../../redux/test/tes';
import { useSelector } from 'react-redux';
import Link from 'next/link';
import { wrapper } from '../../redux/store';
function TestPage({ pageProps }) {
const { data } = useSelector((state) => state.test);
console.log(data);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data && data.map((name) => (
<h1>{name.name}</h1>
))}
</div>
);
}
export const getStaticProps = wrapper.getStaticProps(
(store) => async (context) => {
const loading = store.getState().test.loading;
if (loading === 'idle') {
await store.dispatch(Test('hi'));
}
return {
props: { },
};
}
);
export default TestPage;
现在的问题是商店没有更新
useSelector return []
虽然 console.log (data)
来自 getStaticProps 的数据存在
__NEXT_REDUX_WRAPPER_HYDRATE__
我卡住了
#2更新
到达这里真的很难,在那之后,使用 Next js 获取 Redux 仍然存在问题
现在一切正常,直到导航到任何页面 getStaticProps
或 getServerProps
状态自动重置
store.js
import reducers from './rootReducer';
import { configureStore } from '@reduxjs/toolkit';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
const reducer = (state, action) => {
if (action.type === HYDRATE) {
let nextState = {
...state,
...action.payload,
};
return nextState;
} else {
return reducers(state, action);
}
};
const isDev = process.env.NODE_ENV === 'development';
const makeStore = (context) => {
let middleware = [];
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(middleware),
devTools: isDev,
preloadedState: undefined,
});
return store;
};
export const wrapper = createWrapper(makeStore, { debug: isDev });
1.) Does using Redux with Nextjs eliminate the SEO advantage?
不,将 Redux 与 NextJs 一起使用不会妨碍 SEO 优势。 Redux 与 NextJS 配合得很好。
问题在于您对数据获取的实现。 NextJS 看不到获取的内容,因为您需要在 getInitialProps
、getServerSideProps
或 getStaticProps
中获取它,具体取决于您希望应用程序的工作方式。
请参阅 NextJS 的 Data Fetching documentation。
请注意,getServerSideProps
和 getStaticProps
是处理数据获取的推荐方法。
如果您选择 getStaticProps
,则需要 getStaticPaths
。检查此答案以查看用例和
TLDR;不要将数据获取放在 useEffect 挂钩中,而是将其移动到 getServerSideProps
或 getStaticProps
函数中。
最后只用这个方法 即使服务器和客户端状态分离也不起作用
rootReducer.js
const rootReducer = createReducer(
combinedReducers(undefined, { type: '' }),
(builder) => {
builder
.addCase(HYDRATE, (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff = stateDiff?.test?.data?.[0];
const isdiff1 =
stateDiff?.test1?.data?.[0]
return {
...state,
...action.payload,
test: isdiff ? action.payload.test : state.test,
test1: isdiff1 ? action.payload.test1 : state.test1,
};
})
.addDefaultCase(combinedReducers);
}
);
这里唯一的问题是你必须测试状态中每一块的每一个变化
最佳答案留到悬赏结束,谢谢大家
更新: 因为全球水合物还原剂可能会矫枉过正。 这是一个处理每个切片中水合作用的示例
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { diff } from 'jsondiffpatch';
import { HYDRATE } from 'next-redux-wrapper';
const initialState = {
data: [],
};
export const TestFetch = createAsyncThunk(
'TestFetch',
async (data, { rejectWithValue, dispatch }) => {
try {
const response = await fetch(
'https://jsonplaceholder.typicode.com/users'
);
const d = await response.json();
return d;
} catch (error) {
return rejectWithValue(error.response.data.error);
}
}
);
const test = createSlice({
name: 'test',
initialState,
reducers: {
update: {
reducer: (state, { payload }) => {
return { ...state, data: payload };
},
},
},
extraReducers: {
[HYDRATE]: (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff1 = stateDiff?.server?.[0]?.test?.data?.[0];
// return {
// ...state,
// data: isdiff1 ? action.payload.server.test.data : state.data,
// };
state.data = isdiff1 ? action.payload.server.test.data : state.data;
},
[TestFetch.fulfilled]: (state, action) => {
state.data = action.payload;
},
},
});
export const { update } = test.actions;
export default test.reducer;