[英]How to handle state using Redux with periodical updates and React Hooks?
我刚刚开始使用带有 Hooks 和 Redux 的 React (Native),并且在理解我的用例的状态更新概念的某些部分时遇到了一些问题。 我目前正在开发一个 React Native 应用程序,它应该每整分钟更新一次数据。 因此,如果用户在11h:31m:27s
进入应用程序,
setTimeout
使用偏移量处理第一次更新以达到整分钟(在本例中为33s
达到11h:32m:00s
)setInterval
从现在开始处理数据的每一次更新。目前,使用下面的代码, reducers.js
文件中的console.log("Reducer Fires!")
每隔一分钟就会越来越多地被触发(例如,第一分钟只触发一次,然后第二分钟两次,依此类推)。 所以我觉得我在如何处理我的数据状态以及setInterval()
和setTimeout()
逻辑方面仍然做错了。 有人可以查看我下面的代码并指出我正在做的错误吗?
一些虚拟data
:
export const DATA = [
{"id": 1, "myAttr": 0},
{"id": 2, "myAttr": 4},
{"id": 3, "myAttr": 8},
{"id": 4, "myAttr": 12},
]
带有 redux 存储的App.js
文件:
import React from 'react';
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import { View } from 'react-native';
// Components
import MyComponent from "./components/MyComponent";
import dataReducer from "./store/reducers";
//Create Redux store
const rootReducer = combineReducers({
mydata: dataReducer
});
const store = createStore(rootReducer);
export default function App() {
return (
<Provider store={store} >
<View>
<MyComponent />
</View>
</Provider>
);
}
存储我的 Redux 操作的actions.js
文件:
//Action to update the data
export const UPDATE_DATA = "UPDATE_DATA";
export const updateData = () => {
return { type: UPDATE_DATA }
}
用于存储减速器的reducers.js
文件:
import { DATA } from "../data/data";
import { UPDATE_DATA } from "./actions";
// Initial state when app launches
const initState = {
data: DATA
}
const dataReducer = (state = initState, action) => {
switch (action.type) {
case UPDATE_DATA:
//Update an attribute in each object of the data array
const updatedData = state.data.map((i) => {
const newMyAttr = i.myAttr + 1;
return { ...i, myAttr: newMyAttr }
}
)
console.log("Reducer Fires!");
return { ...state, data: updatedData }
default:
return state;
}
};
export default dataReducer;
我试图更新状态的component
:
import React, { useEffect, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { Text, View } from 'react-native';
const MyComponent = (props) => {
const myData = useSelector(state => state.mydata.data);
let start = new Date();
const fullMinuteOffset = (60 - start.getSeconds()) * 1000;
const dispatch = useDispatch();
const saveData = useCallback(() => {
dispatch(updateData())
}, [dispatch]);
useEffect(() => {
const timer = setTimeout(() => {
saveData()
const interval = setInterval(() => {
saveData()
}, 60000)
return () => clearInterval(interval);
}, fullMinuteOffset);
return () => clearTimeout(timer);
}, [saveData, fullMinuteOffset]);
return(
<View>
<Text>{myData[0].myAttr}</Text>
</View>
);
};
export default MyComponent;
每次组件渲染时,它都会有一个新的 fullOffserMinute 值,它是 useEffect 的依赖项,因此注册了一个新的间隔调用。
这是您的代码的简化工作示例:
https://codesandbox.io/s/jolly-panini-k35s1?fontsize=14&hidenavigation=1&theme=dark
// the relevant part of it
let start = new Date();
let [counter, setCounter] = useState(0);
const fullMinuteOffset = (60 - start.getSeconds()) * 1000;
function timerAction() {
setCounter(counter => counter + 1);
};
useEffect(() => {
console.log("-- use effect --");
const timer = setTimeout(() => {
console.log("save data timeout");
timerAction();
const interval = setInterval(() => {
console.log("save data interval");
timerAction();
}, 5000);
return () => clearInterval(interval);
}, fullMinuteOffset);
return () => clearTimeout(timer);
}, []);
如果您打算按时间间隔更新本地状态,您还应该在这里阅读答案: 在 setInterval 内使用 React 状态挂钩时状态不更新
如果您将 useEffect 依赖项更改为: [saveTime, fullMinuteOffset]
-> 到[]
。 似乎每次 useEffect 调用的组件更新可能会注册更多间隔
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.