我想在next.js中使用redux-saga进行api调用。
// sagas/deliveries.js
import axios from 'axios';
import { put, takeEvery, all, fork, call } from 'redux-saga/effects';
import {
LOAD_DELIVERIES_REQUEST,
loadDeliveriesSuccess,
loadDeliveriesFailure,
} from '../reducers/deliveries';
function* loadDeliveries() {
try {
const { data } = yield axios.get(`${process.env.SERVER}/deliveries`);
yield put(loadDeliveriesSuccess(data));
} catch (error) {
console.error(error);
yield put(loadDeliveriesFailure(error));
}
}
function* watchLoadDeliveries() {
yield takeEvery(LOAD_DELIVERIES_REQUEST, loadDeliveries);
}
export default function* deliveriesSaga() {
yield all([fork(watchLoadDeliveries)]);
}
// reducers/deliveries.js
// Action
export const LOAD_DELIVERIES_REQUEST = 'LOAD_DELIVERIES_REQUEST';
export const LOAD_DELIVERIES_SUCCESS = 'LOAD_DELIVERIES_SUCCESS';
export const LOAD_DELIVERIES_FAILURE = 'LOAD_DELIVERIES_FAILURE';
export const loadDeliveriesRequest = () => ({ type: LOAD_DELIVERIES_REQUEST });
export const loadDeliveriesSuccess = data => ({ type: LOAD_DELIVERIES_SUCCESS, data });
export const loadDeliveriesFailure = error => ({ type: LOAD_DELIVERIES_FAILURE, error });
// Reducer
const initialState = {
deliveryPosts: [],
error: '',
};
export default function deliveries(state = initialState, action) {
switch (action.type) {
case LOAD_DELIVERIES_SUCCESS:
return { ...state, deliveryPosts: action.data };
case LOAD_DELIVERIES_FAILURE:
return { ...state, error: action.error };
default:
return state;
}
}
// pages/_app.js
function MyApp({ Component, pageProps, store }) {
const router = useRouter();
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
MyApp.getInitialProps = async ({ Component, ctx }) => {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
};
const configureStore = (initialState, options) => {
const sagaMiddleware = createSagaMiddleware();
const middlewares = [sagaMiddleware];
const enhancer =
process.env.NODE_ENV === 'production'
? compose(applyMiddleware(...middlewares))
: composeWithDevTools(applyMiddleware(...middlewares));
const store = createStore(rootReducer, initialState, enhancer);
store.sagaTask = sagaMiddleware.run(rootSaga);
return store;
};
export default withRedux(configureStore)(withReduxSaga(MyApp));
// pages/posts.tsx
Posts.getInitialProps = async context => {
await context.store.dispatch({ type: LOAD_DELIVERIES_REQUEST });
console.log(context.store.getState().deliveries.deliveryPosts); // It is empty!
return { posts: posts.data, deliveryPosts: context.store.getState().deliveries.deliveryPosts };
但是我刷新页面或更多输入此页面,deliveryPosts是。
我认为在以SUCCESS操作获取数据之前,先返回getState()数据。 在getInitialProps中调度REQUEST时,如何在SUCCESS之后获取数据?
useDispatch和useSelector不能在getInitialProps中使用