Next.js 使用 Link 导航时,next-redux-wrapper 状态被重置为初始值
Next.js with next-redux-wrapper state is being reset to initial value when navigating using Link
Next.js v12.0
next-redux-wrapper.
每当我使用适当的 next/link 元素离开页面然后再次返回(使用另一个 link el)时,状态将重置为初始值,因此会执行另一个提取。奇怪的是,我以相同的方式设置了另一个 'transaction' 切片,除了它包含一组事务对象并且工作正常(导航离开和返回并且数据不会重新获取为它保留在商店中)代码低于任何建议将不胜感激。
store.js
import { HYDRATE, createWrapper } from "next-redux-wrapper";
import thunkMiddleware from "redux-thunk";
import address from "./address/reducer";
import transactions from "./transaction/reducer";
const bindMiddleware = (middleware) => {
if (process.env.NODE_ENV !== "production") {
const { composeWithDevTools } = require("redux-devtools-extension");
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
const combinedReducer = combineReducers({
transactions,
address,
});
const rootReducer = (state, action) => {
if (action.type === HYDRATE) {
const nextState = {
...state, // use previous state
...action.payload, // apply delta from hydration
};
if (state.address.id){
nextState.address = state.address;
}
return nextState;
} else {
return combinedReducer(state, action);
}
};
const initStore = () => {
return createStore(rootReducer, bindMiddleware([thunkMiddleware]));
};
export const wrapper = createWrapper(initStore);
address/reducer.js
const addressInitialState = {
id: null,
timestamp: null,
address: null,
balance: null,
received: null,
sent: null,
groupid: null,
last_txs: []
};
export default function reducer(state = addressInitialState, action) {
switch (action.type) {
case addressActionTypes.GET_WALLET_DETAILS:
return {id: action.payload.address, ...action.payload};
default:
return state;
}
}
address/action.js
export const addressActionTypes = {
GET_WALLET_DETAILS: "GET_WALLET_DETAILS",
};
export const getWalletDetails = (address) => {
return async (dispatch) => {
const fetchData = async () => {
const response = await fetch(
`https:someapi.com/api/getaddress/?address=${address}`
);
if (!response.ok) {
throw new Error("Could not fetch address data!");
}
const data = await response.json();
console.log('req sent');
return data;
};
try {
const addressData = await fetchData();
dispatch({
type: addressActionTypes.GET_WALLET_DETAILS,
payload: addressData,
});
} catch (err) {
console.log(err);
}
};
};
页数/[地址].js
import { Fragment } from "react";
import Head from "next/head";
import AddressDetails from "../../../components/crypto/rvn/AddressDetails";
import AddressTransactions from "../../../components/crypto/rvn/AddressTransactions";
import { connect } from "react-redux";
import { getWalletDetails } from "../../../store/address/action";
import { wrapper } from "../../../store/store";
function Address(props) {
return (
<Fragment>
<Head>
<title>RVN</title>
<meta name="description" content="RVN Address" />
</Head>
<AddressDetails address={props.addressDetails}></AddressDetails>
<AddressTransactions
transactions={props.addressDetails["last_txs"]}
address={props.addressDetails.address}
></AddressTransactions>
</Fragment>
);
}
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async (context) => {
const state = store.getState();
if(state.address.id === null) {
await store.dispatch(getWalletDetails(context.params.address));
}
else{
return{
props: {
addressDetails: state.address,
}
}
}
}
);
const mapStateToProps = (state) => ({
addressDetails: state.address,
});
export default connect(mapStateToProps, null)(Address);
通过转换解决了这个问题
const initStore = () => {
return createStore(rootReducer, bindMiddleware([thunkMiddleware]));
};
在store.js
直接来自 https://github.com/vercel/next.js/tree/canary/examples/with-redux-thunk
至此
const store = createStore(rootReducer, bindMiddleware([thunkMiddleware]));
const initStore = () => {
return store
};
因此它不会在每次使用包装器时都重新初始化存储
这更符合文档在
https://github.com/kirill-konshin/next-redux-wrapper
Next.js v12.0
next-redux-wrapper.
每当我使用适当的 next/link 元素离开页面然后再次返回(使用另一个 link el)时,状态将重置为初始值,因此会执行另一个提取。奇怪的是,我以相同的方式设置了另一个 'transaction' 切片,除了它包含一组事务对象并且工作正常(导航离开和返回并且数据不会重新获取为它保留在商店中)代码低于任何建议将不胜感激。
store.js
import { HYDRATE, createWrapper } from "next-redux-wrapper";
import thunkMiddleware from "redux-thunk";
import address from "./address/reducer";
import transactions from "./transaction/reducer";
const bindMiddleware = (middleware) => {
if (process.env.NODE_ENV !== "production") {
const { composeWithDevTools } = require("redux-devtools-extension");
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
const combinedReducer = combineReducers({
transactions,
address,
});
const rootReducer = (state, action) => {
if (action.type === HYDRATE) {
const nextState = {
...state, // use previous state
...action.payload, // apply delta from hydration
};
if (state.address.id){
nextState.address = state.address;
}
return nextState;
} else {
return combinedReducer(state, action);
}
};
const initStore = () => {
return createStore(rootReducer, bindMiddleware([thunkMiddleware]));
};
export const wrapper = createWrapper(initStore);
address/reducer.js
const addressInitialState = {
id: null,
timestamp: null,
address: null,
balance: null,
received: null,
sent: null,
groupid: null,
last_txs: []
};
export default function reducer(state = addressInitialState, action) {
switch (action.type) {
case addressActionTypes.GET_WALLET_DETAILS:
return {id: action.payload.address, ...action.payload};
default:
return state;
}
}
address/action.js
export const addressActionTypes = {
GET_WALLET_DETAILS: "GET_WALLET_DETAILS",
};
export const getWalletDetails = (address) => {
return async (dispatch) => {
const fetchData = async () => {
const response = await fetch(
`https:someapi.com/api/getaddress/?address=${address}`
);
if (!response.ok) {
throw new Error("Could not fetch address data!");
}
const data = await response.json();
console.log('req sent');
return data;
};
try {
const addressData = await fetchData();
dispatch({
type: addressActionTypes.GET_WALLET_DETAILS,
payload: addressData,
});
} catch (err) {
console.log(err);
}
};
};
页数/[地址].js
import { Fragment } from "react";
import Head from "next/head";
import AddressDetails from "../../../components/crypto/rvn/AddressDetails";
import AddressTransactions from "../../../components/crypto/rvn/AddressTransactions";
import { connect } from "react-redux";
import { getWalletDetails } from "../../../store/address/action";
import { wrapper } from "../../../store/store";
function Address(props) {
return (
<Fragment>
<Head>
<title>RVN</title>
<meta name="description" content="RVN Address" />
</Head>
<AddressDetails address={props.addressDetails}></AddressDetails>
<AddressTransactions
transactions={props.addressDetails["last_txs"]}
address={props.addressDetails.address}
></AddressTransactions>
</Fragment>
);
}
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async (context) => {
const state = store.getState();
if(state.address.id === null) {
await store.dispatch(getWalletDetails(context.params.address));
}
else{
return{
props: {
addressDetails: state.address,
}
}
}
}
);
const mapStateToProps = (state) => ({
addressDetails: state.address,
});
export default connect(mapStateToProps, null)(Address);
通过转换解决了这个问题
const initStore = () => {
return createStore(rootReducer, bindMiddleware([thunkMiddleware]));
};
在store.js 直接来自 https://github.com/vercel/next.js/tree/canary/examples/with-redux-thunk
至此
const store = createStore(rootReducer, bindMiddleware([thunkMiddleware]));
const initStore = () => {
return store
};
因此它不会在每次使用包装器时都重新初始化存储
这更符合文档在 https://github.com/kirill-konshin/next-redux-wrapper