前回はUI部分の実装が終わったので、次はReduxの設定とデータを入れるところまでの解説です。
公式のリポジトリを参考にしていきます。
github.com/zeit/next.js/tree/master/examples/with-redux
まずは、Redux関連のライブラリをインストール
yarn add redux react-redux redux-devtools-extension redux-logger
store.jsを作成
import { createStore, applyMiddleware } from 'redux' import { composeWithDevTools } from 'redux-devtools-extension' import logger from 'redux-logger' const initialState = { memoList: [] } export const actionTypes = { CREATE: 'CREATE', } export const reducer = (state = initialState, action) => { switch (action.type) { case actionTypes.CREATE: let memoList = state.memoList memoList.push(action.data.memo) return { ...state, memoList } default: return state } } export const createMemo = (memo) => { return { type: actionTypes.CREATE, data: { memo } } } export const deleteMemo = (index) => { return { type: actionTypes.DELETE, data: index } } export function initializeStore (initialState = initialState) { return createStore( reducer, initialState, composeWithDevTools(applyMiddleware(logger)) ) }
メモを追加する処理を記述。redux-loggerでconsoleでチェックできるようにしておきます。
lib/with-redux-store.jsを作成し、下記を記述。
import React from 'react'
import { initializeStore } from '../store'
const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'
function getOrCreateStore (initialState) {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
return initializeStore(initialState)
}
// Create store if unavailable on the client and set it on the window object
if (!window[__NEXT_REDUX_STORE__]) {
window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
}
return window[__NEXT_REDUX_STORE__]
}
export default App => {
return class AppWithRedux extends React.Component {
static async getInitialProps (appContext) {
// Get or Create the store with `undefined` as initialState
// This allows you to set a custom default initialState
const reduxStore = getOrCreateStore()
// Provide the store to getInitialProps of pages
appContext.ctx.reduxStore = reduxStore
let appProps = {}
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext)
}
return {
...appProps,
initialReduxState: reduxStore.getState()
}
}
constructor (props) {
super(props)
this.reduxStore = getOrCreateStore(props.initialReduxState)
}
render () {
return <App {...this.props} reduxStore={this.reduxStore} />
}
}
}
Appを受け取ってstoreと接続する関数です。
pages/_app.js
import App, { Container } from 'next/app' import React from 'react' import withReduxStore from '../lib/with-redux-store' import { Provider } from 'react-redux' console.dir(withReduxStore) class MyApp extends App { render () { const { Component, pageProps, reduxStore } = this.props return ( <Container> <Provider store={reduxStore}> <Component {...pageProps} /> </Provider> </Container> ) } } export default withReduxStore(MyApp)
pages/_app.jsを作成しAppコンポーネントをオーバーライドします。
これで、Reduxの接続は完成
ページコンポーネントを修正
pages/new.jsをコンテナにします。
import React, { Component } from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' import { actions } from '../store' import NewComponent from '../components/new' const mapStateToProps = () => { return { } } const mapDispatchToProps = (dispatch) => { return { ...bindActionCreators(actions, dispatch) } } export default connect(mapStateToProps, mapDispatchToProps)(NewComponent)
次にコンポーネントを作成
components/new.js
const New = (props) => { const handleSubmit = (e) => { e.preventDefault() const target = e.target const title = target.title.value const content = target.content.value props.createMemo({ title, content }) } return ( <div> <h1>メモ作成</h1> <div> <form onSubmit={handleSubmit}> <div> <div> <label htmlFor="">タイトル</label> </div> <input type="text" name="title" placeholder="title"/> </div> <div> <div> <label htmlFor="">本文</label> </div> <textarea name="content" placeholder="content"/> </div> <div> <input type="submit" value="submit"/> </div> </form> </div> </div> ) }
これでフォームに値を入れてsubmitすると
無事、memoListに追加されました。
本日はここまで、次回はルーティング周りの実装をしていきたいと思います。
フロントエンド開発でお困りのことはありませんか?
フロントエンドの開発支援を行っています。
・Reactの開発をお願いしたい
・コーディング作業を依頼したい
・javascriptライブラリを作って欲しい。
上記以外にも何かありましたらお気軽にお問い合わせください。