React

連載[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter

連載[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter

[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter
[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter

業務で使いそうな予感したから触っておく

※この連載の2はこちら

チュートリアル

フォルダ構成

(reduxメンテナー「Mark Erikson」のフォルダ構成はfeaturesのなかにhogeSlice、hogePageが滞在していた)

フォルダ構成。[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter
フォルダ構成。[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter

src/features/counterPage.tsx

import * as React from "react"
import * as ReactRedux from "react-redux"
import * as CounterModule from "./counterSlice"
import { RootState } from "../rootReducer"
import Button from "../components/Button"

export function Component(){
  const dispatch = ReactRedux.useDispatch()
  const count = ReactRedux.useSelector<RootState, number>((state) => state.counter.count) // useSelectorの第一型変数はRootState, 第二は返す型

  const onClickDown = () => {
    dispatch(CounterModule.countDown(-1)) // いったん
  }

  const onClickUp = () => {
    dispatch(CounterModule.countUp(1)) //いったん
  }

  return (
    <React.Fragment>
      <div>{count}</div>
      <Button onClick={() => onClickUp()} text="up" />
      <Button onClick={() => onClickDown()} text="down" />
    </React.Fragment>
  )
}

/src/components/Button.tsx


import * as React from "react"

type Props = {
  text: string
  onClick: () => void
}
function Button(props : Props) {
  return (
    <button onClick={props.onClick}>{props.text}</button>
  )
}

export default Button

src/features/counterSlice.ts


import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { RootState } from "../rootReducer"

type State = {
  count: number
}

const initialState: State = {
  count: 1
}

const counter = createSlice({
  name: "counter",
  initialState,
  reducers: {
    countUp: (state: State, action: PayloadAction<number>) => { // PayloadActionには渡ってくる型を
      state.count - action.payload
    },
    countDown: (state: State, action: PayloadAction<number>) => {
      state.count + action.payload // 内部でimmer使っているので
    }
  }
})

export const { countUp, countDown } =  counter.actions

export default counter.reducer

src/rootReducer.ts

import { combineReducers } from "@reduxjs/toolkit"
import counterModules from "./features/counterSlice"

const rootReducer = combineReducers({
  counter: counterModules
})

export type RootState = ReturnType<typeof rootReducer>

export default rootReducer

src/store.ts

import { configureStore } from '@reduxjs/toolkit'

import rootReducer from "./rootReducer"

const store = configureStore({
  reducer: rootReducer
})

export type AppDispatch = typeof store.dispatch

export default store

src/App.ts

import React from 'react';
import * as Counter from "./features/CounterPage"
import './App.css';

function Component() {
  return (
    <div className="App">
      <Counter.Component />
    </div>
  );
}

export default Component;

src/index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as App from './App';
import { Provider } from "react-redux"
import store from "./store"

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

sandbox

次回はthunkのところをやって示しますね


「武骨日記の」プライバシーポリシーに関して
プライバシーポリシー
個人情報取り扱いに関して

サイトTOP
私は何者か
29歳よしもと芸人がWebデザイナー未経験で学校に通い5年後フリーランスのフロントエンドエンジニアになるためにやった9つのこと
フロント記事
フロントエンドエンジニア
フロントエンド記事(タグ)
TypeScript
TypeScript練習問題集
【TypeScript】TypeSript中級者になる為に知っておくと良い108個のこと
JavaScript練習問題
styled-componentsの使い方
SCSS問題集
GraphQL「Apollo x Relay-Style-Cursor-Pagination(リレースタイルカーソルページネーション)」
recomposeと仲良くなりたい
機動戦士FlowType
初めてReactNativeWebを触ってみて
Ramda.jsシグネチャの読み方
環境変数の話
いちごタルトの作り方
フロントエンドエンジニア豚汁の作り方


「武骨日記の」プライバシーポリシーに関して
プライバシーポリシー

株式会社TerraceTechについて
最近起業しました。
株式会社TerraceTech

SNS
インド旅 instagram
適当な日常写真 instagram
シュールさーん instagram
シュールさーん LINEスタンプ
もりたけんじTwitter
ネタ帳Twitter
note

FaceBook -kennji.morita-

わたしが結成しているWebチームではWeb未経験者、フリーランスの方へのお仕事を紹介しています。
また個人レッスンしてほしい生徒も募集中です。
もしご興味ある方はチャットからご連絡ください。

※業務連絡やお久しぶり連絡もチャットからお願いします。