【发布时间】:2021-06-09 17:05:27
【问题描述】:
我的应用程序允许用户单击“字段”部分中的球员卡,然后让选定的球员卡出现在“团队”部分中。我有一个数组(称为 selectedPlayers),最初,每个元素都有一个默认玩家名称和默认玩家图像。当用户选择球员时,数组中的元素会被所选球员的姓名和图像一一替换。
在父组件中设置数组的状态,然后将数组作为道具传递给 TeamsWrapper 组件。然后我映射数组,为数组的每个元素返回一个 TeamsCard 组件。然而,我的 TeamsCards 总是落后于现实的一种选择。也就是说,在第一个玩家被选中后,第一张牌仍然显示默认信息;选择第二个玩家后,第一张卡现在反映第一次选择,但第二张卡仍显示默认信息。 TeamsWrapper 组件的代码如下:
import React from "react";
import "./style.css";
import TeamsCard from "../TeamsCard";
function TeamsWrapper(props) {
const { selectedPlayers } = props;
console.log('first console.log',selectedPlayers)
return (
<div className="teamsWrapper">
{selectedPlayers.map((el, i) => {
console.log('second console.log',selectedPlayers)
console.log('third console.log',el)
return (
<div key={i}>
<TeamsCard
image={el.image}
playerName={el.playerName}
/>
</div>
);
})}
</div>
);
}
export default TeamsWrapper;
在父级是基于类的组件之前,我确实可以正常工作。但是,我将其更改为使用钩子用于其他目的的功能组件。所以,我认为这个问题与设置状态有关,但控制台日志表明其他东西(我认为)。选中第一个玩家后:
- 第一个控制台日志显示了一个正确更新的数组(即第一个元素反映了所选玩家的数据,而不是占位符数据)
- 第二个控制台日志反映了同样的情况
- 但第三次打印仍然显示第一个元素的占位符数据
如上所述,当我继续选择球员时,第三张印刷品(以及 TeamsCards)总是落后一个选择。
编辑:
这里是父组件(Picks)的代码,但是我把不相关的内容删掉了,以便于理解。
import React, { useState } from "react";
import { useStateWithCallbackLazy } from "use-state-with-callback";
import TeamsWrapper from "../TeamsWrapper";
import FieldWrapper from "../FieldWrapper";
const Picks = () => {
const initialSelectedPlayers = [
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
];
const [count, setCount] = useStateWithCallbackLazy(0);
const [selectedPlayers, setSelectedPlayers] = useState(
initialSelectedPlayers
);
const handleFieldClick = (props) => {
// check to make sure player has not already been picked
const match = selectedPlayers.some(
(el) => el.playerName === props.playerName
);
if (match) {
return;
} else {
setCount(count + 1, (count) => {
updatePickPhase(props, count);
});
}
};
const updatePickPhase = (props, count) => {
if (count <= 15) {
updateTeams(props, count);
}
// elseif other stuff which doesn't apply to this issue
};
const updateTeams = (props, count) => {
const location = [0, 1, 2, 5, 4, 3];
const position = location[count - 1];
let item = { ...selectedPlayers[position] };
item.playerName = props.playerName;
item.image = props.image;
selectedPlayers[position] = item;
setSelectedPlayers(selectedPlayers);
};
return (
<>
<TeamsWrapper selectedPlayers={selectedPlayers}></TeamsWrapper>
<FieldWrapper
handleFieldClick={handleFieldClick}
count={count}
></FieldWrapper>
</>
);
};
export default Picks;
感谢您的帮助!
【问题讨论】:
-
这个组件应该像你期望的那样工作。我们需要查看存储状态的父级。可能会引起您注意的是,如果您修改数组,控制台将反映这一点,即使您在修改它之前记录了它。一般来说,在更新状态时,您应该创建新对象而不是修改以前的对象。
-
Ben,感谢您提供有关控制台日志记录的想法和提示。已添加父组件,尽管我不得不对其进行一些简化以专注于该问题。
标签: javascript reactjs methods