我正在开发使用SSR的应用程序。它基于React,Next和Redux。我了解拥有客户端存储和服务器存储并使其彼此同步的一般概念。
我正在使用next-redux-wrapper,但似乎无法让服务器端存储来维持其状态。
_app.js
// pages/_app.js
import React from 'react'
import {Provider} from "react-redux";
import App, {Container} from "next/app";
import withRedux from "next-redux-wrapper";
import makeStore from "../state/index.js";
class MyApp extends App {
static async getInitialProps({Component, ctx}) {
// we can dispatch from here too
// ctx.store.dispatch({type: 'FOO', payload: 'foo'});
const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
return {pageProps};
}
render() {
const {Component, pageProps, store} = this.props;
return (
<Container>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</Container>
);
}
};
export default withRedux(makeStore, {debug: true})(MyApp)
state / reducers / index.js
import { createStore } from 'redux'
import rootReducer from './reducers/index'
const makeStore = (initialState) => {
return createStore(rootReducer, initialState);
};
export default makeStore;
这是page / index.js(登录)
import React, { Component } from "react";
import Head from 'next/head';
import Input from '@material-ui/core/Input';
// import withRedux from 'next-redux-wrapper';
// import initStore from '../state/index.js';
import { connect } from "react-redux";
const mapStateToProps = state => ({
// Login
paypalCredentials: state.login.paypalCredentials
});
const mapDispatchToProps = dispatch => ({
setPaypalCredentials: (payload) => dispatch({ type: 'SET_PAYPAL_CREDENTIALS', payload: payload })
})
class Login extends Component {
static getInitialProps({store, isServer, pathname, query}) {
// store.dispatch({type: 'FOO', payload: 'foo'}); // component will be able to read from store's state when rendered
// return {custom: 'custom'}; // you can pass some custom props to component from here
}
shouldComponentUpdate(nextProps){
// Redirect if Paypal Details are received (after login)
if (nextProps.paypalCredentials !== this.props.paypalCredentials && nextProps.paypalCredentials !== null) {
window.location.assign("/receipt");
return false;
} else {
return true;
}
}
reqPaypalCredentials = async() => {
let res = await fetch("https://api.paypal.com/v1/oauth2/token?grant_type=client_credentials", {
method: "POST",
'headers': {
'Authorization': 'Basic QVFlY3ZXelNPSE05a3VZSE5WZ2p...confidential',
'Content-Type': 'application/x-www-form-urlencoded'
}
}),
data = await res.json();
return data;
}
submitLogin = () => {
console.log("SubmitLogin");
(async() => {
let data = null,
resolvedData = null;
try {
data = this.reqPaypalCredentials();
resolvedData = await data;
this.props.setPaypalCredentials(resolvedData);
} catch (err) {
console.log("There was an error fetching the data: \n", error);
}
})();
}
forgotPassword = () => {
}
render(){
return (
<React.Fragment>
<Head>
<meta charset="utf-8" />
<link rel="stylesheet" href="/static/css/global.css" />
<link rel="stylesheet" href="/static/css/login.css" />
</Head>
<div id="loginBg">
<div id="loginModal">
<div id="loginHeader">
<h2>Akauntu</h2>
<div id="loginLogo"></div>
<h2>Platform</h2>
</div>
<div id="loginContent">
<div>
<Input
autoFocus={true}
placeholder="Email"
required={true}
type="email"
/>
<Input
placeholder="Password"
required={true}
type="password"
/>
</div>
</div>
<div id="loginFooter">
<h3 onClick={ this.submitLogin }>Login</h3>
</div>
<p onClick={ this.forgotPassword }>Forgot Password?</p>
</div>
</div>
</React.Fragment>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);