以下など参考に整理しつつTypeScript化
https://medium.com/@bhavikbamania/a-beginner-guide-for-redux-with-next-js-4d018e1342b2
手順
add package
$ yarn add redux react-redux next-redux-wrapper
$ yarn add --dev @types/react-redux @types/next-redux-wrapper
store
例としてtoken用store
src/reducer/auth.ts
export const LOGIN = 'LOGIN'
export const LOGOUT = 'LOGOUT'
export interface LoginAction {
type: typeof LOGIN
token: string
}
export interface LogoutAction {
type: typeof LOGOUT
}
export interface AuthState {
token: string
}
const initialState: AuthState = {
token: null
}
export default (state = initialState, action) => {
switch (action.type) {
case LOGIN:
return { ...state, token: action.token }
case LOGOUT:
return { token: null }
default:
return state
}
}
src/reducer/index.ts
import { combineReducers } from 'redux'
import auth, { AuthState } from './auth'
export type RootState = {
auth: AuthState
}
export default combineReducers({
auth
})
src/store.ts
import { createStore } from 'redux'
import rootReducer from './reducer'
export const makeStore = (initialState = {}) => {
return createStore(rootReducer, initialState)
}
Providerを_appで組み込む
pages/_app.tsx
import React from 'react'
import App, { AppInitialProps } from 'next/app'
import Head from 'next/head'
import withRedux, { AppProps } from 'next-redux-wrapper'
import { makeStore } from '../src/store'
import { Provider } from 'react-redux'
import { LOGIN } from '../src/reducer/auth'
interface MyAppProps extends AppInitialProps, AppProps {}
export default withRedux(makeStore)(
class MyApp extends App<MyAppProps> {
static async getInitialProps({ Component, ctx }) {
const token = 'TODO'
ctx.store.dispatch({ type: LOGIN, token })
const pageProps = Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}
return { pageProps }
}
render() {
const { Component, pageProps, store } = this.props
return (
<>
<Head>
<title>Hello</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</>
)
}
}
)
pageでuseSelectorとかする
page/index.tsx
import React from 'react'
import { NextPage } from 'next'
import { useSelector } from 'react-redux'
import { RootState } from '../src/reducer'
const Index: NextPage = () => {
const token = useSelector<RootState, string>(s => s.auth.token)
return <div>{token}</div>
}
export default Index