Skip to content
This repository has been archived by the owner on Oct 9, 2024. It is now read-only.

Restore Next's Automatic Static Optimization #183

Merged
merged 2 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 31 additions & 44 deletions pages/_app.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,50 @@
/* global process */
import App from 'next/app';
import React from 'react';
import React, {useEffect, useState} from 'react';
import '../style/scss/style.scss';
import { wrapper } from '../store';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { useStore } from '../store';
import { Provider } from 'react-redux';
import commerce from '../lib/commerce';
import { loadStripe } from '@stripe/stripe-js';
import { setCustomer } from '../store/actions/authenticateActions';

class MyApp extends App {
constructor(props) {
super(props);
const MyApp = ({Component, pageProps}) => {

// If using Stripe, initialise it here. This allows Stripe to track behaviour
// as much as possible in order to determine fraud risk.
this.stripePromise = null;
const store = useStore(pageProps.initialState);
const [stripePromise, setStripePromise] = useState(null);

useEffect(() => {
if (process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY) { // has API key
this.stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
setStripePromise(loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY));
}
}

stripePromise = null;

componentDidMount() {
this.props.setCustomer();
}
setCustomer();

static async getInitialProps({ Component, ctx }) {
// Fetch products
// Fetch categories
const { data: products } = await commerce.products.list();
const { data: categories } = await commerce.categories.list();
commerce.products.list().then((res) => {
store.dispatch({
type: 'STORE_PRODUCTS',
payload: res.data
})
});

// Allows store to be updated via the dispatch action
ctx.store.dispatch({ type: 'STORE_CATEGORIES', payload: categories });
ctx.store.dispatch({ type: 'STORE_PRODUCTS', payload: products });
commerce.categories.list().then((res) => {
console.log(res.data)
store.dispatch({
type: 'STORE_CATEGORIES',
payload: res.data
})
});

return {
pageProps: {
// Call page-level getInitialProps
...(Component.getInitialProps ? await Component.getInitialProps(ctx) : {}),
}
};
}
}, [store])

render() {
const { Component, pageProps } = this.props;

return (
return (
<Provider store={store}>
<Component
{...pageProps}
stripe={this.stripePromise}
stripe={stripePromise}
/>
);
}
</Provider>
);

}

export default compose(
wrapper.withRedux, // HOC wrapper
connect(null, { setCustomer }) // function that returns wrapper
)(MyApp);
export default MyApp;
41 changes: 37 additions & 4 deletions store/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo } from 'react'
import { createStore, applyMiddleware, compose } from 'redux';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
import { HYDRATE } from 'next-redux-wrapper';
import thunk from 'redux-thunk';

import {
Expand All @@ -19,6 +20,7 @@ import {
CLEAR_CUSTOMER,
} from './actions/actionTypes';

let store
// Declare initial state
const initialState = {
categories: [],
Expand Down Expand Up @@ -108,6 +110,8 @@ const reducer = (state = initialState, action) => {
}
};



// Enable Redux dev tools
const devtools = (process.browser && window.__REDUX_DEVTOOLS_EXTENSION__)
? window.__REDUX_DEVTOOLS_EXTENSION__(
Expand All @@ -124,7 +128,36 @@ const makeStore = () => {
);
};

const debug = !process.env.NETLIFY;

// Export an assembled wrapper with store's data
export const wrapper = createWrapper(makeStore, { debug });
export const initializeStore = (initialState) => {
let _store = store ?? makeStore(initialState)

// After navigating to a page with an initial Redux state, merge that state
// with the current state in the store, and create a new store
if (initialState && store) {
_store = makeStore({
...store.getState(),
...initialState,
})
// Reset the current store
store = undefined
}

// For SSG and SSR always create a new store
if (typeof window === 'undefined') {
return _store
}
// Create the store once in the client
if (!store) {
store = _store
}

return _store
}


export function useStore(initialState) {
const store = useMemo(() => initializeStore(initialState), [initialState])
return store
}