似乎无法使用 Redux Toolkit 获取更新状态

时间:2021-06-22 12:19:19

标签: redux react-redux react-hooks state redux-toolkit

我正在使用 Tone.js 和 redux 工具包制作 React 应用程序,但在获取读取更新状态的函数时遇到问题。我似乎能够在单击按钮时更新状态,但它并未反映在下面的 thisWillRepeat 函数中。

在下面的代码中,我理想情况下只需要 Tone.Transport.scheduleRepeat 运行一次。 Tone.Transport.scheduleRepeat 在回调函数的参数中接受预定事件的确切时间,并且可以通过 startStopHandler() 进行控制。我尝试了很多方法,包括添加 [theState] 作为第二个 useEffect 参数,但由于安排了许多额外的重复,这会导致一团糟。我确定我缺少一些基本的东西。

主要应用组件

import React, { useEffect } from 'react'
import * as Tone from 'tone'

import { useSelector, useDispatch } from 'react-redux'
import { songActions } from '../store/index'

const Sequencer = () => {

  const theState = useSelector(state => state.theSong)
  const dispatch = useDispatch()

  const startStopHandler = () => {
    dispatch(songActions.startStopHandler())
    !theState.isPlaying ? Tone.Transport.start() : Tone.Transport.stop()
  }

  const changeTheState = () => dispatch(songActions.updateAbitOfState())

  // why doesn't the state update in the console.log below after updating it successfully with buttons below?
  const thisWillRepeat = () => console.log(theState.drums)

  useEffect(() => {
    Tone.Transport.scheduleRepeat((time) => { 
      thisWillRepeat(time)
    }, '8n')
  },[])

  return <> 
      <button onClick={() => startStopHandler()}>Play / Pause</button>
      <br/>
      A bit of state in the store has the value of: {theState.drums}
      <br/>
      <button onClick={() => changeTheState()}>Change the state</button>
      <button onClick={() => console.log(theState)}>Click to get the state</button>
    </>
}

export default Sequencer

商店

import { createSlice, configureStore } from '@reduxjs/toolkit'

const initialSongState = {
  isPlaying: false,
  drums: 'not changed'
}

const songSlice = createSlice({
  name: 'theSong',
  initialState: initialSongState,
  reducers: {
    startStopHandler(state){
      state.isPlaying = !state.isPlaying
    },
    updateAbitOfState(state) {
      state.drums = 'something new!'
    }
  }
})

const store = configureStore({
  reducer: {
    theSong: songSlice.reducer
  }
})

export const songActions = songSlice.actions

export default store

1 个答案:

答案 0 :(得分:1)

您已经创建了一个闭包,它在组件首次呈现时捕获了 theState

const thisWillRepeat = () => console.log(theState.drums)

根据定义,它可以永远指向后面渲染的值。

要阅读最新状态,您需要:

  • 直接访问商店并在回调中调用 store.getState()
  • 使用引用,在此之上的另一个效果中分配 refObj.current = theState,然后 console.log(refObj.current)
  • 将组件外部的逻辑移到 Redux thunk 中,它也可以访问 getState

请参阅 Dan Abramov 的帖子 A Complete Guide to useEffect 以更好地了解闭包以及 useEffect 如何与值交互。