首页 > 解决方案 > Redux 不会更新状态

问题描述

我是第一次使用 Redux,我的演示应用程序不会更新其默认状态。我也尝试过使用 useEffect 订阅我的状态,但仍然没有记录更新的状态。

动作.ts

import { createAction } from '@reduxjs/toolkit'

export const setUsername = createAction<string>('auth/setUsername')
export const setPassword = createAction<string>('auth/setPassword')
export const setModalOpen = createAction<boolean>('auth/setModalOpan')

钩子.ts

import { useCallback, useMemo } from 'react'
import { setUsername,setPassword,setModalOpen } from './actions'
import { useSelector, useDispatch } from 'react-redux'
import {IAuth} from './reducer'
import {AppState} from '../index'

export function useSetUsername(): (payload:string)=>void {
  const dispatch = useDispatch()
  return useCallback((payload)=>dispatch(setUsername(payload)), [dispatch])
}

export function useSetPassword(): (payload:string)=>void {
  const dispatch = useDispatch()
  return useCallback((payload)=>dispatch(setPassword(payload)), [dispatch])
}

export function useSetModalOpen(): (payload:boolean)=>void {
  const dispatch = useDispatch()
  return useCallback((payload)=>dispatch(setModalOpen(payload)), [dispatch])
}

export function useGetAuthState():IAuth {
  return useSelector((state:AppState)=>state.payload)
}

减速器.ts

import { createReducer } from '@reduxjs/toolkit'
import {setUsername, setPassword, setModalOpen} from './actions'

export interface IAuth{
  username: string;
  password: string;
  modalOpen: boolean;
}

const initialState:IAuth = {
  username: '',
  password: '',
  modalOpen: false
}

export default createReducer(initialState, builder=>
  builder
.addCase(setUsername, (state ,action)=>{
  state = {...state, username:action.payload}
})
.addCase(setPassword,(state,action)=>{
  state = {...state, password:action.payload}
})
.addCase(setModalOpen,(state,action)=>{
  state = {...state, modalOpen:action.payload}
})
  )

实现.tsx

import React, {useState, useEffect, useRef, useLayoutEffect} from 'react';
import { Route, Switch, useRouteMatch, useParams} from 'react-router-dom';
import {useSetPassword, useSetUsername, useSetModalOpen, useGetAuthState} from './state/auth/hooks'

function Review():JSX.Element {
  const match = useRouteMatch()
  const authState = useGetAuthState()
  const setUsername = useSetUsername()
  setUsername('why wont this work?')


  function Topic(){
    let {topicId} = useParams<{topicId:string}>()
    console.log(authState)
    console.log(topicId)
    return <>The topic is... {topicId}</>
  }

  function Main(){
    return (
      <div>
        Primary Page
      </div>
    )
  }

  return(
    <Switch>
      <Route path={`${match.path}/:topicId`}>
        <Topic/>
      </Route>
      <Route path={`${match.path}/`}>
        <Main />
      </Route>
    </Switch>
  )
}

export default Review;

我想运行 setUsername(),然后记录 getAuthState() 的结果输出。当我运行它时,我只是在日志中获得我的默认状态。我尝试使用 useEffect 订阅 authState,但这对我来说没有任何改变。

谢谢你。

标签: reactjsreduxreact-reduxredux-toolkit

解决方案


您需要在每个addCase

因此,将您的减速器更改为:

export const store = createReducer(initialState, (builder) =>
  builder
    .addCase(setUsername, (state, action) => ({
      ...state,
      username: action.payload,
    }))
    .addCase(setPassword, (state, action) => ({
      ...state,
      password: action.payload,
    }))
    .addCase(setModalOpen, (state, action) => ({
      ...state,
      modalOpen: action.payload,
    }))
);

工作示例:

编辑 Amazing-cohen-4imhi


推荐阅读