連載[最短で理解する] ReduxToolKit(React x TypeScript) example minimum counter
業務で使いそうな予感したから触っておく
※この連載の2はこちら
フォルダ構成
(reduxメンテナー「Mark Erikson」のフォルダ構成はfeaturesのなかにhogeSlice、hogePageが滞在していた)
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')
);
次回は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
・しずかなインターネット kenjimorita
・インド旅 instagram
・適当な日常写真 instagram
・シュールさーん instagram
・シュールさーん LINEスタンプ
・もりたけんじTwitter
・ネタ帳Twitter
・note
※わたしが結成しているWebチームではWeb未経験者、フリーランスの方へのお仕事を紹介しています。
また個人レッスンしてほしい生徒も募集中です。
もしご興味ある方はチャットからご連絡ください。
※業務連絡やお久しぶり連絡もチャットからお願いします。