如何在计时器上更新Redux存储值?

xzabzqsa  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(149)

我正在使用更多的reudx,并试图显示一个有效的值。初始状态设置为0。
我的目标是每秒将该值递增1。为了实现这一点,我做了如下操作:

setInterval(() => {
    dispatch(Increment());
  }, 1000);

它并没有真正按照我想要的方式工作,即使它在以极快的速度递增。
另外,另一个问题。在我的reducer中,理论上我想做这样的表达式:

Increment: (state) => {
      state.value + 1;
    },

但是当我这样做的时候,redux会抛出以下错误:
应为赋值或函数调用,但看到的却是表达式
在redux reducer中是否不可能做这样的表达式?

yk9xbfzb

yk9xbfzb1#

首先你的函数没有return语句

Increment: (state) => {
  state.value + 1;
},

试着把它改成

Increment: (state) => {
  return state.value + 1;
},

或者使用括号()来代替使用{()}

Increment: (state) => (
  state.value + 1;
),

另外,不要忘记归约器是纯函数................................................................................................................................................................................................................................................
减速器应该是这样的

const initialState = { count: 0 };
export default function reducer(state = initialState, action) {
  switch(action.type) {
     case 'INCREMENT':  
       return {         
        count: state.count + 1       
      };     
     case 'DECREMENT':       
       return {         
       count: state.count - 1       
      };     
     default:       
       return state;   
  } 
}

然后,您应该有一个操作,您可以使用这样的类型进行调度

dispatch({type:'INCREMENT'})

因为您已经有了一个操作助手函数
是这样的

function increment() {
   return {
   type: "INCREMENT"
  } 
};

function decrement() {
   return {
   type: "DECREMENT"
  } 
};

你就能做到

setInterval(() => {
    dispatch(increment());
  }, 1000);
z31licg0

z31licg02#

应为赋值或函数调用,但看到的却是表达式
state.value + 1创建了一个比state.value大1的数字,但是你没有对这个值做任何事情。当它说“期望赋值”时,它意味着你期望将创建的数字赋值给一个变量,比如const someVariable = state.value + 1
有一些运算符将赋值和操作结合在一起。你不需要创建一个新的变量,因为这些运算符会更新现有变量的值。这就是你在这里要做的。你可以像这样使用addition assignment operator +=state.value += 5。或者您可以通过写入state.value++来使用increment operator ++添加1。这两个操作都会修改草稿状态的state.value属性。
您应该阅读本指南:

至于在定时器上更新,您希望在useEffect钩子中初始化setInterval调用。您希望存储创建的间隔的id,以便在组件卸载或按下“停止”按钮时通过调用clearInterval来停止调度。
下面是一个示例代码:

import { useState, useRef, useEffect } from "react";
import { increment, decrement, incrementByAmount } from "../store/slice";
import { useSelector, useDispatch } from "../store";

export const Counter = () => {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  const [isRunning, setIsRunning] = useState(false);

  const intervalId = useRef<number>();

  useEffect(() => {
    // helper function to stop an existing timer
    const clear = () => {
      if (intervalId.current) {
        clearInterval(intervalId.current);
      }
    };

    // start the timer
    if (isRunning) {
      intervalId.current = setInterval(() => {
        dispatch(increment());
      }, 1000);
    }
    // stop the timer when isRunning becomed false
    else {
      clear();
    }

    // cleanup function stops the timer when the component unmounts
    return clear;
  }, [dispatch, isRunning]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <div>
        <button onClick={() => setIsRunning(true)} disabled={isRunning}>
          Start Timer
        </button>
        <button onClick={() => setIsRunning(false)} disabled={!isRunning}>
          Stop Timer
        </button>
      </div>
    </div>
  );
};

export default Counter;

Code Sandbox Link

相关问题