typescript + react + redux toolkit counter

16674 ワード

TS + REACT + RTK COUNTER


Reduxはやはりcounterをしてこそ感じられる.
最新のRTK方式を更新し、フォローします.
参考資料
https://redux-toolkit.js.org/tutorials/typescript
https://codesandbox.io/s/qo6l3?file=/src/App.tsx
私が作成したTS Resact RTKカウンタ
RTKの紹介に従って作成します.

改善点

  • の従来のstore内部状態を選択する方法が改良され、コールバック関数を用いてより容易に選択できるようになった.
    (独自のhookを作成する必要があります)
  • store file tree



    store.tsx

    import { configureStore } from "@reduxjs/toolkit"; 
    import counterReducer from "./counterReducer"; 
    
    export const store = configureStore({
    	reducer:{
    		counters:counterReducer
    	},devTools:true
    })
    
    export type RootState = ReturnType<typeof  store.getState> // custom hook 
    export type AppDispatch=typeof store.dispatch 
    export type RootState = ReturnType<typeof  store.getState> 
    https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype
    TSのReturnTypeを使用します.
    出力タイプ.
    root stateを導くtype
    export type AppDispatch=typeof store.dispatch
    
    割り当てるタイプの推定に使用

    hooks.ts

    import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
    import type { RootState, AppDispatch } from './store';
    
    
    export const useAppDispatch = () => useDispatch<AppDispatch>();
    export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
    useAppDispatchからAppDispatch = typeof store.dispatchスケジューリングステータスのタイプを指定します.

    counterReducer.tsx

    import { createSlice, PayloadAction } from "@reduxjs/toolkit";
    import type { RootState } from './store'
    
    interface CounterState{
    	value:number
    }
    
    const initialState:CounterState={
    	value:0,
    }
    
    export const counterSlice = createSlice({
    	name:'counter',
    	initialState,
    	reducers:{
    		increment:(state)=>{
    			console.log('increment')
    			state.value +=1
    		},
    		decrement:(state)=>{
    			console.log('decrement')
    			state.value -=1
    		},
    		incrementByAmount:(state,action:PayloadAction<number>)=>{
    			state.value += action.payload
    		},
    	}
    })
    
    export const { increment, decrement, incrementByAmount} = counterSlice.actions
    export const selectValue = (state:RootState) =>state.counters.value;
    export default counterSlice.reducer
    sliceは既存とほぼ同じです.

    counter.tsx

    import React, { useState } from 'react'
    
    import { useAppSelector, useAppDispatch } from './store/hooks'
    import { decrement, increment, incrementByAmount } from './store/counterReducer';
    
    export function Counter() {
      const count = useAppSelector(state=>state.counters.value);
      const dispatch = useAppDispatch()
      return(
    	  <div>
    		  <h1>{count}</h1>
    		  <button onClick={()=>dispatch(increment())}>increment</button>
    		  <button onClick={()=>dispatch(decrement())}>decrement</button>
    		  <button onClick={()=>dispatch(incrementByAmount(10))}>10 increment</button>
    	  </div>
      )
    }
    変数count, dispatchから見ると、従来とは異なり、custom hookを用いるuseAppSelectorconst useAppSelector: TypedUseSelectorHook<RootState> = useSelector;はい.既存のUserSelectorを指定するタイプと考えられます.
    変数dispatchはuseAppDispatch()を使用します.useAppDispatch = () => useDispatch<AppDispatch>(); type AppDispatch=typeof store.dispatch type AppDispatchはstoreディスパッチ状態のtypeからgenericを読み込みます.