我正在尝试使用useReducer更新组件的状态。我在useEffect中从mongodb获取了一些信息,在那里我调用了我的useReducer dispatch,以便在组件装载后立即设置我的状态。不幸的是,我的状态没有受到影响,我的UI也没有改变。控制台。useffect语句末尾的log语句显示我的状态仍然具有useReducer调用中设置的初始值。有人能告诉我哪里出了问题吗?另外,我计划稍后在useffect中添加到state和依赖项数组中。以前,当我在做这个的时候,我得到了一个无限的useEffect循环,所以现在我有一个空的错误。不过我想更新状态,让我的UI反映更改。另外,下面是包含useEffect调用的功能组件的代码。
编辑:我的玩家对象最初应该是我当前与mongodb一起使用的用户的对象{健康百分比:100,饥饿百分比:100,水合百分比:100}
const change_progress_color = (pet_percentage: any) => {
// change the attribute's color depending on pet_attr value
// PROGRESS_COLORS IS JUST AN ENUM OBJ WITH COLOR CODES
let color;
if (pet_percentage < .10)
color = PROGRESS_COLORS[1];
else if (pet_percentage < .30)
color = PROGRESS_COLORS[2];
else if (pet_percentage < .50)
color = PROGRESS_COLORS[3];
else if (pet_percentage < .75)
color = PROGRESS_COLORS[4];
else if (pet_percentage < .90)
color = PROGRESS_COLORS[5];
else
color = PROGRESS_COLORS[6];
return color;
};
const Player: React.FC = () => {
const [player, setPlayer] = useState<any>();
const [state, dispatch] = useReducer<React.Reducer<State, Actions>>(reducer,
{health: 0, hydration: 0, hunger: 0});
useEffect(() => {
console.log("running useEffect");
(async () => {
var my_player = await getPlayer();
if (my_player)
if (my_player.length > 0) {
const p: any = my_player[0];
setPlayer(p);
console.log("here is my player", p);
dispatch({type: "ChangeHealth", diff: p.health_percent});
dispatch({type: "ChangeHunger", diff: p.hunger_percent});
dispatch({type: "ChangeHydration", diff: p.hydration_percent});
console.log("Here is my state", state);
}
})();
}, []);
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>My Player</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">My Player</IonTitle>
</IonToolbar>
</IonHeader>
<IonList>
<IonItem>
<IonLabel position="floating">
Health
</IonLabel>
<IonProgressBar
value={state.health}
color={change_progress_color(state.health)}/>
</IonItem>
<IonItem>
<IonLabel position="floating">
Hunger
</IonLabel>
<IonProgressBar
value={state.hunger}
color={change_progress_color(state.hunger)}/>
</IonItem>
<IonItem>
<IonLabel position="floating">
Hydration
</IonLabel>
<IonProgressBar
value={state.hydration}
color={change_progress_color(state.hydration)}/>
</IonItem>
</IonList>
</IonContent>
</IonPage>
);
};
export default Player;
下面是我在react函数之外的代码,以及我的类型和reducer函数。
type State = {
health: number;
hunger: number;
hydration: number;
};
type ChangeHealth = {
readonly type: "ChangeHealth";
readonly diff: number; // this number is going to need to be divided by 100
}
type ChangeHunger = {
readonly type: "ChangeHunger";
readonly diff: number; // this number is going to need to be divided by 100
}
type ChangeHydration = {
readonly type: "ChangeHydration";
readonly diff: number; // this number is going to need to be divided by 100
}
type Actions = ChangeHealth | ChangeHunger | ChangeHydration;
function reducer(state: State, action: Actions): State {
switch (action.type) {
case "ChangeHealth":
return (() => {
console.log("running func");
console.log("here is the diff ", action.diff);
let new_health = (state.health + action.diff) / 100;
console.log(new_health);
if (new_health > 1)
new_health = 1;
return {...state, health: new_health};
} )();
case "ChangeHunger":
return (() => {
let new_hunger = (state.hunger + action.diff) / 100;
if (new_hunger > 1)
new_hunger = 1;
return {...state, hunger: new_hunger};
} )();
case "ChangeHydration":
return (() => {
let new_hydration = (state.hydration + action.diff) / 100;
if (new_hydration > 1)
new_hydration = 1;
return {...state, hydration: new_hydration};
} )();
}
}
任何帮助都将不胜感激。谢谢
你只提出一个要求。为什么要将数据拆分为use State和use Reaver?
下面的MB代码帮助您。
import React, { useEffect, useState } from 'react';
const Player: React.FC = () => {
const [player, setPlayer] = useState({
health: 0,
hydration: 0,
hunger: 0,
});
useEffect(() => {
getPlayer()
.then((response) => {
const [player] = response;
if (player) {
setPlayer((prevState) => {
const health = (prevState.health + player.health_percent) / 100;
const hunger = (prevState.hunger + player.hunger_percent) / 100;
const hydration = (prevState.hydration + player.hydration_percent) / 100;
return ({
health: health > 1 ? 1 : health,
hunger: hunger > 1 ? 1 : hunger,
hydration: hydration > 1 ? 1 : hydration,
});
});
}
})
.catch(({ message }) => {
console.error(message);
});
}, []);
return null;
};
您的useEffect和Reducer代码很好,状态如您所期望的那样更新,这就是上次控制台更新的原因。日志未记录新状态是因为,分派方法不同步,它会导致重新渲染,并在下一次渲染时更新新状态。我认为您的问题是显示状态
问题内容: 这可能看起来很奇怪。 我已经用Java(在Eclipse中)编写了代码。然后,我对代码进行了一些修改。现在,我正在尝试运行新代码(已修改),但是它仍然为我提供了先前代码的输出。 我在代码中放置了很少的调试点,但是它跳过了一些调试点(尽管它应该在它们处停止)并在某个调试点处停止,但是即使在这里,它也调用了先前代码中存在的方法。位置(尽管我已经对此发表了评论)。从某个地方看来,它仍然在调试
我已经设置了一个谷歌工作表,它附带了一个脚本,运行一个函数来提取chromebook设备信息,除了我感兴趣的两个字段,“cpuStatusReports”和“diskVolumeReports”之外,效果非常好。脚本记录器确实显示了正确的信息,但我的工作表单元格值设置为例如 {cpuUtilizationPercentageInfo=[Ljava.lang.Object;@d151552,cpuT
我有一个django模型,它的id开始奇怪地增加。 列的后缀定义(从詹戈模型生成): 然后我通过django管理员创建了一个新记录: 然后我创建了一个新记录,它跳过了值17224,并插入了主键17225: 有人知道为什么会发生这种情况吗?应用程序此时并不关心,因为id仍在增加,但是在过去的几个新对象中,PKs已经从427跳过-
招呼: 我认为我没有正确更新我的复杂状态: 如何正确更新此状态?谢谢 https://codesandbox.io/s/intelligent-ellis-qi97k?file=/src/App.js
我正在尝试创建一个SNMP4j代理,但发现很难正确理解该过程。我已经成功创建了一个可以使用snmpwalk从命令行查询的代理。我遇到的困难是理解如何更新存储在我实现的MIB中的值。 下面显示了我用于创建MIB的相关代码(我实现了主机资源MIB) 这似乎足以创建可运行的代理。我不明白的是,我应该如何更改MIB中存储的值(例如,如何更改HrSWRunStatus的值)。似乎有一些乱七八糟的方法,但它们
我使用useReducer保存一些状态,如下面的代码所示,但它没有从array reducer函数返回值。 过程: 当我单击屏幕上的按钮时,它会从数据库中获取信息 该信息存储在batchEntries变量中 当批次条目发生更改时,我使用useEffect由雇主触发DispatchEntries 这会导致减速器运行 我知道内部减少函数会运行,因为如果我把它包装在控制台日志中,它会将我期望的数据输出到