如何在 React/Framer 的数组中查找特定项?
How to find specific items in an array in React/Framer?
我正在从 API 中提取结果,如下所示:
const [state, setState] = React.useState({
matches: undefined,
chosenBets: [{}]
});
const API = "https://api.myjson.com/bins/i461t"
const fetchData = async (endpoint, callback) => {
const response = await fetch(endpoint);
const json = await response.json();
setState({ matches: json });
};
并使用 map()
函数基于它渲染 JSX:
export function MatchCardGroup(props) {
return (
<div>
{props.matches.map((match, i) => {
return (
<MatchCard
key={i}
matchCardIndex={i}
team_home={match.teams[0]}
team_away={match.teams[1]}
league_name={match.sport_nice}
odd_home={match.sites[0].odds.h2h[0]}
odd_draw={match.sites[0].odds.h2h[1]}
odd_away={match.sites[0].odds.h2h[2]}
onClick={props.onClick}
timestamp={match.timestamp}
/>
);
})}
</div>
);
}
然后我有一张卡片,上面有赔率,每个赔率都有自己的点击事件:
export function MatchCard(props) {
const [state, setState] = React.useState({
selection: {
id: undefined
}
});
const {
timestamp,
team_home,
team_away,
league_name,
odd_away,
odd_draw,
odd_home,
onClick,
matchCardIndex,
selection
} = props;
const odds = [
{
id: 0,
label: 1,
odd: odd_home || 1.6
},
{
id: 1,
label: "X",
odd: odd_draw || 1.9
},
{
id: 2,
label: 2,
odd: odd_away || 2.6
}
];
const handleOnClick = (odd, oddIndex) => {
// need to changhe the selection to prop
if (state.selection.id === oddIndex) {
setState({
selection: {
id: undefined
}
});
onClick({}, matchCardIndex);
} else {
setState({
selection: {
...odd,
team_home,
team_away
}
});
onClick({ ...odd, oddIndex, team_home, team_away, matchCardIndex });
}
};
React.useEffect(() => {}, [state, props]);
return (
<div style={{ width: "100%", height: 140, backgroundColor: colour.white }}>
<div>
<span
style={{
...type.smallBold,
color: colour.betpawaGreen
}}
>
{timestamp}
</span>
<h2 style={{ ...type.medium, ...typography }}>{team_home}</h2>
<h2 style={{ ...type.medium, ...typography }}>{team_away}</h2>
<span
style={{
...type.small,
color: colour.silver,
...typography
}}
>
{league_name}
</span>
</div>
<div style={{ display: "flex" }}>
{odds.map((odd, oddIndex) => {
return (
<OddButton
key={oddIndex}
oddBackgroundColor={getBackgroundColour(
state.selection.id,
oddIndex,
colour.lime,
colour.betpawaGreen
)}
labelBackgroundColor={getBackgroundColour(
state.selection.id,
oddIndex,
colour.lightLime,
colour.darkBetpawaGreen
)}
width={"calc(33.3% - 8px)"}
label={`${odd.label}`}
odd={`${odd.odd}`}
onClick={() => handleOnClick(odd, oddIndex)}
/>
);
})}
</div>
</div>
);
}
在我的 App
组件中,我正在记录单击事件返回的对象:
const onClick = obj => {
// check if obj exists in state.chosenBets
// if it exists, remove from array
// if it does not exist, add it to the array
if (state.chosenBets.filter(value => value == obj).length > 0) {
console.log("5 found.");
} else {
console.log(state.chosenBets, "state.chosenBets");
}
};
我想做的是:
- 当用户点击任何给定匹配项的奇数时,将该奇数添加到
chosenBets
- 如果用户取消选择奇数,则从
chosenBets
中删除该奇数
- 任何时候只能从任何比赛的 3 种可能赔率中选择 1 种赔率
奖励积分:所选奇数是根据 App
中的全局状态而不是局部状态选择的。如果我在其他地方编辑数组,它应该在 UI.
中更新
任何帮助将不胜感激,我在这里迷路了!
我已经简要了解了您的项目,这里有一些建议可以帮助您:
对象仅通过引用相等。
这意味着
{ id: 0, matchCardIndex: 8 } === { id: 0, matchCardIndex: 8 }
是假的,即使你期望它是真的。要比较它们,您需要比较对象中的每个键:
value.id === obj.id && value.matchCardIndex === obj.matchCardIndex
这也会影响您在 index.tsx
中的过滤器调用,因此您应该将那里的比较更改为类似于
的内容
state.chosenBets.filter(value => value.id === obj.id && value.matchCardIndex === obj.matchCardIndex)
国家应该只住一个地方
正如您已经提到的,最好将状态保存在您的 index.tsx 中(如果您在那里也需要),并且不要将其保存在组件树中更下方的组件中。我建议让组件仅呈现状态,并使用处理程序来更改状态。
例子
这是您的代码沙箱的分支,我认为它是以您描述的方式实现的:https://codesandbox.io/s/gifted-star-wg629-so-pg5gx
我正在从 API 中提取结果,如下所示:
const [state, setState] = React.useState({
matches: undefined,
chosenBets: [{}]
});
const API = "https://api.myjson.com/bins/i461t"
const fetchData = async (endpoint, callback) => {
const response = await fetch(endpoint);
const json = await response.json();
setState({ matches: json });
};
并使用 map()
函数基于它渲染 JSX:
export function MatchCardGroup(props) {
return (
<div>
{props.matches.map((match, i) => {
return (
<MatchCard
key={i}
matchCardIndex={i}
team_home={match.teams[0]}
team_away={match.teams[1]}
league_name={match.sport_nice}
odd_home={match.sites[0].odds.h2h[0]}
odd_draw={match.sites[0].odds.h2h[1]}
odd_away={match.sites[0].odds.h2h[2]}
onClick={props.onClick}
timestamp={match.timestamp}
/>
);
})}
</div>
);
}
然后我有一张卡片,上面有赔率,每个赔率都有自己的点击事件:
export function MatchCard(props) {
const [state, setState] = React.useState({
selection: {
id: undefined
}
});
const {
timestamp,
team_home,
team_away,
league_name,
odd_away,
odd_draw,
odd_home,
onClick,
matchCardIndex,
selection
} = props;
const odds = [
{
id: 0,
label: 1,
odd: odd_home || 1.6
},
{
id: 1,
label: "X",
odd: odd_draw || 1.9
},
{
id: 2,
label: 2,
odd: odd_away || 2.6
}
];
const handleOnClick = (odd, oddIndex) => {
// need to changhe the selection to prop
if (state.selection.id === oddIndex) {
setState({
selection: {
id: undefined
}
});
onClick({}, matchCardIndex);
} else {
setState({
selection: {
...odd,
team_home,
team_away
}
});
onClick({ ...odd, oddIndex, team_home, team_away, matchCardIndex });
}
};
React.useEffect(() => {}, [state, props]);
return (
<div style={{ width: "100%", height: 140, backgroundColor: colour.white }}>
<div>
<span
style={{
...type.smallBold,
color: colour.betpawaGreen
}}
>
{timestamp}
</span>
<h2 style={{ ...type.medium, ...typography }}>{team_home}</h2>
<h2 style={{ ...type.medium, ...typography }}>{team_away}</h2>
<span
style={{
...type.small,
color: colour.silver,
...typography
}}
>
{league_name}
</span>
</div>
<div style={{ display: "flex" }}>
{odds.map((odd, oddIndex) => {
return (
<OddButton
key={oddIndex}
oddBackgroundColor={getBackgroundColour(
state.selection.id,
oddIndex,
colour.lime,
colour.betpawaGreen
)}
labelBackgroundColor={getBackgroundColour(
state.selection.id,
oddIndex,
colour.lightLime,
colour.darkBetpawaGreen
)}
width={"calc(33.3% - 8px)"}
label={`${odd.label}`}
odd={`${odd.odd}`}
onClick={() => handleOnClick(odd, oddIndex)}
/>
);
})}
</div>
</div>
);
}
在我的 App
组件中,我正在记录单击事件返回的对象:
const onClick = obj => {
// check if obj exists in state.chosenBets
// if it exists, remove from array
// if it does not exist, add it to the array
if (state.chosenBets.filter(value => value == obj).length > 0) {
console.log("5 found.");
} else {
console.log(state.chosenBets, "state.chosenBets");
}
};
我想做的是:
- 当用户点击任何给定匹配项的奇数时,将该奇数添加到
chosenBets
- 如果用户取消选择奇数,则从
chosenBets
中删除该奇数
- 任何时候只能从任何比赛的 3 种可能赔率中选择 1 种赔率
奖励积分:所选奇数是根据 App
中的全局状态而不是局部状态选择的。如果我在其他地方编辑数组,它应该在 UI.
任何帮助将不胜感激,我在这里迷路了!
我已经简要了解了您的项目,这里有一些建议可以帮助您:
对象仅通过引用相等。
这意味着
{ id: 0, matchCardIndex: 8 } === { id: 0, matchCardIndex: 8 }
是假的,即使你期望它是真的。要比较它们,您需要比较对象中的每个键:
value.id === obj.id && value.matchCardIndex === obj.matchCardIndex
这也会影响您在 index.tsx
中的过滤器调用,因此您应该将那里的比较更改为类似于
state.chosenBets.filter(value => value.id === obj.id && value.matchCardIndex === obj.matchCardIndex)
国家应该只住一个地方
正如您已经提到的,最好将状态保存在您的 index.tsx 中(如果您在那里也需要),并且不要将其保存在组件树中更下方的组件中。我建议让组件仅呈现状态,并使用处理程序来更改状态。
例子
这是您的代码沙箱的分支,我认为它是以您描述的方式实现的:https://codesandbox.io/s/gifted-star-wg629-so-pg5gx