LoginSignup
0
0

More than 3 years have passed since last update.

脳内メモリ使わず初期設定(create-react-app)その3

Last updated at Posted at 2020-03-05

react最初の設定を反芻。徐々に改善していくスタイル。。

その1
https://qiita.com/DaisukeNishi/items/c8982546c803d2c5dc99
その2
https://qiita.com/DaisukeNishi/items/57cb3a440ddfb876ee9a

環境構築を反芻して覚える。

image.png

グローバルインストール(初回のみ)

npm i -g create-react-app
sudo npm install eslint -g
sudo npm i -g eslint-plugin-react

プロジェクト(名前例)react_1231を作る。

create-react-app react_`date '+%m%d'`
cd react_`date '+%m%d'`

git初期化

git init
open .gitignore

セーブポイント除外。

.history

yarnで必要なもの一通り

yarn add react-app-rewired customize-cra styled-jsx axios immer react-app-polyfill react-router-dom react-transition-group react-redux redux redux-devtools redux-thunk node-sass styled-jsx-plugin-sass

空ディレクトリ作成 

mkdir -p src/components/common/common src/components/common/home src/components/common/list src/components/common/detail src/components/pc/common src/components/pc/home src/components/pc/list src/components/pc/detail src/components/sp/common src/components/sp/home src/components/sp/list src/components/sp/detail src/assets/img src/scss src/views src/components/pc/notfound src/components/sp/notfound src/components/pc/about src/components/sp/about src/components/pc/company src/components/sp/company src/components/pc/policy src/components/sp/policy src/components/pc/terms src/components/sp/terms src/components/pc/contact src/components/sp/contact src/store

空ファイル作成

touch config-overrides.js .babelrc.json src/Template.js src/components/common/common/Header.js src/components/common/common/Menu.js src/components/common/common/Footer.js src/store/index.js src/store/actions.js src/store/reducer.js

テンプレート作成

open src/Template.js
src/Template.js
import React,{Fragment} from 'react'
import { connect } from 'react-redux'

const render = () => {
  return (
  <Fragment>
    <div className="">

    </div>
    <style jsx>{`

    `}</style>
  </Fragment>
  )
}

// eslint-disable-next-line no-unused-vars
const mapState = (state) =>{
  return {

  }
}

// eslint-disable-next-line no-unused-vars
const mapDispatch = (dispatch) => {
  return {

  }
}

export default connect(mapState, mapDispatch)(render)

テンプレート配置

cd src
find . -name "*" -type d -exec cp Template.js {} \;
cd ../
rm src/App.css src/scss/Template.js src/assets/Template.js src/assets/img/Template.js src/components/Template.js src/components/common/Template.js src/components/pc/Template.js src/components/sp/Template.js src/store/Template.js

CRA設定ファイル編集

open config-overrides.js
config-overrides.js
const { override,useBabelRc,useEslintRc,disableEsLint} = require("customize-cra");
module.exports = override(
  useBabelRc(".babelrc.json"),
  useEslintRc(".eslintrc.json"),
  //disableEsLint()
);

package.json編集

open package.json
package.json
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
  //(中略)
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not ie <= 10", //追加
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }

babel設定編集

open .babelrc.json
babelrc.json
{
  "presets": [
    "react-app"
  ],
  "plugins": [
    ["styled-jsx/babel",{ "plugins": ["styled-jsx-plugin-sass"]}]
  ]
}

eslint初期設定

eslint --init

>To check syntax and find problems
>JavaScript modules (import/export) 
>React
Typescript? N
Where code run?
◎ Browser
◎ Node
What format?
>JSON
eslint@latest install? Y

最後に"extends"の内容を編集する

"extends": [
    "react-app"
],

redux用のstoreファイル編集

open src/store/index.js
src/store/index.js
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import * as actions from './actions'
import thunk from 'redux-thunk'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(
  reducer,
  composeEnhancers(applyMiddleware(thunk))
)
export default store
export { reducer, actions }
open src/store/actions.js
src/store/actions.js
import axios from 'axios'

export const showSide = () => ({
  type: 'showSide'
})

export const hideSide = () => ({
  type: 'hideSide'
})

export const changeL = () => ({
  type: 'changeL'
})

export const showLR = (val) =>({
  type: 'showLR',
  val
})
open src/store/reducer.js
src/store/reducer.js
import produce from "immer"
import { combineReducers } from 'redux'

const defaultState = {
  sideBar: false,
  blurStyle: {},
  cover: false,
  L: true,
  LR: false
}

const mutations = {
  showSide (state, action) {
    return produce(state, (state) => {
      state.sideBar = true
      state.cover = true
      state.blurStyle = {transform: 'translateX(15rem)', filter: 'blur(3px)'}
    })
  },
  hideSide (state, action) {
    return produce(state, (state) => {
      if (state.LR) {
        state.LR = false
      } else {
        state.sideBar = false
      }
      state.cover = false
      state.blurStyle = {}
    })
  }
}

const store = (state = defaultState, action) => {
  if (mutations[action.type]) {
    return mutations[action.type](state, action)
  }
  return state
}

export default combineReducers({
  store
})
open src/index.js
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './store'
import { Provider } from 'react-redux'

ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'))
serviceWorker.unregister();

コンポーネント編集

open src/components/common/common/Header.js
src/components/common/common/Header.js
import React, {Fragment} from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { actions } from '../../../store'

const render = (props) => {
  return (
    <Fragment>
      <div className="header">
        <span className="button" onClick={props.showSide}>
          
        </span>
        <Link to='/'>
          <span className="title">react-app</span>
        </Link>
      </div>
      <style jsx>{`
        .header{
          position: fixed;
          top: 0;
          right: 0;
          left: 0;
          z-index: 5;
          background-color: #fff;
          box-shadow: 0 3px 15px 0px #0001;
          vertical-align: middle;
          color: #02b3e4;

          .button{
            height: 4rem;
            line-height: 4rem;
            display: inline-block;
            padding: 0 1rem;
            text-align: center;
            font-weight: 800;
            font-size: 1.2rem;
          }

          .title{
            font-size: 1.4rem;
            font-weight: bold;
            margin-left: 1.5%;
            height: 3rem;
            line-height: 3rem;
          }
        }
      `}</style>
    </Fragment>
  )
}

// eslint-disable-next-line no-unused-vars
const mapState = (state) =>{
  return {
  }
}

// eslint-disable-next-line no-unused-vars
const mapDispatch = (dispatch) => {
  return {
    showSide() {
      dispatch(actions.showSide())
    }
  }
}

export default connect(mapState, mapDispatch)(render)
open src/components/common/common/Menu.js
src/components/common/common/Menu.js
import React, {Fragment} from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { actions } from '../../../store'

const render = (props) => {
  return (
    <Fragment>
      <div className="bar">
        <div className="btn-wrapper">
          <Link to="/">
            <span type="button" className="btn btn-light" onClick={props.hideSide}>閉じる</span>
          </Link>
        </div>
      </div>

      <style jsx>{`
      .bar{
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: 15rem;
        background-color: #fff;
        padding-top: 2rem;
        box-shadow: 0px 2px 20px #0003;
        z-index: 6;

        .btn-wrapper{
          height: 4.5rem;
          line-height: 4.5rem;
          text-align: center;
        }
      }
    `}</style>
    </Fragment>
  )
}

// eslint-disable-next-line no-unused-vars
const mapState = (state) =>{
  return {
  }
}

// eslint-disable-next-line no-unused-vars
const mapDispatch = (dispatch) => {
  return {
    hideSide () {
      dispatch(actions.hideSide())
    }
  }
}

export default connect(mapState, mapDispatch)(render)
open src/components/common/common/Footer.js
src/components/common/common/Footer.js
import React,{Fragment} from 'react'
import { connect } from 'react-redux'

const Footer = () => {
  return (
    <Fragment>
      <div className="footer">
        Copyright@XXX-XXX co,Ltd.
      </div>
      <style jsx>{`
        .footer{
          color: #777;
          margin-top: 0rem;
          height: 4rem;
          line-height: 4rem;
          text-align: center;
          background-color: #efefef;
        }
      `}</style>
    </Fragment>
  )
}

export default connect(null, null)(Footer)
open src/App.js
src/App.js
import React, { Fragment } from 'react';
import { connect } from 'react-redux'
import logo from './logo.svg';

import { BrowserRouter }  from 'react-router-dom'
import { actions } from './store'

import Header from './components/common/common/Header'
import Footer from './components/common/common/Footer'
import Menu from './components/common/common/Menu'

import { CSSTransition } from 'react-transition-group'

function App( props ) {

  return (
    <Fragment>
      <BrowserRouter>
        {/* HTML */}
        <div className="App">
          <Header></Header>
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a>
          </header>
          <Footer></Footer>
          <CSSTransition in={props.sideBar} timeout={300} classNames="fade" unmountOnExit>
            <Menu />
          </CSSTransition>
        </div>
        {/* CSS */}
        <style jsx>{`
          .App {
            text-align: center;
          }

          .App-logo {
            height: 40vmin;
            pointer-events: none;
          }

          @media (prefers-reduced-motion: no-preference) {
            .App-logo {
              animation: App-logo-spin infinite 20s linear;
            }
          }

          .App-header {
            background-color: #282c34;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            font-size: calc(10px + 2vmin);
            color: white;
          }

          .App-link {
            color: #61dafb;
          }

          @keyframes App-logo-spin {
            from {
              transform: rotate(0deg);
            }
            to {
              transform: rotate(360deg);
            }
          }
        `}</style>

      </BrowserRouter>
    </Fragment>
  );
}

// eslint-disable-next-line no-unused-vars
const mapState = (state) => {
  return {
    sideBar: state.store.sideBar,
  }
}

// eslint-disable-next-line no-unused-vars
const mapDispatch = (dispatch) => {
  return {
    hideSide () {
      dispatch(actions.hideSide())
    }
  }
}

export default connect(mapState, mapDispatch)(App)
yarn start
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0