Javascript React钩子,有条件地更改onClick函数内的状态,在下一次单击时更新
您好,我有一个列表组件,它呈现一些Javascript React钩子,有条件地更改onClick函数内的状态,在下一次单击时更新,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,您好,我有一个列表组件,它呈现一些组件,这些组件具有属性isSelected。因为当组件具有isSelected==true时,会发生很多事情,我在组件上添加了状态,并且我希望当有人单击一张卡进行检查时: 1) 如果没有以前选择的项目(state===null将该项目的id添加到state) 2) 如果有人单击同一项或另一项,而状态中已选择了一项,则仅取消选中活动项 import {Card} from "./Card"; import cloneDeep from 'lodash/cloneD
组件,这些组件具有属性
isSelected
。因为当
组件具有isSelected==true
时,会发生很多事情,我在
组件上添加了状态,并且我希望当有人单击一张卡进行检查时:
1) 如果没有以前选择的项目(state===null
将该项目的id添加到state)
2) 如果有人单击同一项或另一项,而状态中已选择了一项,则仅取消选中活动项
import {Card} from "./Card";
import cloneDeep from 'lodash/cloneDeep';
const List = () => {
const [selectedCard, setSelectedCard] = useState(null);
const onCardClick = id => {
console.debug(selectedCard, id)
const newSelectedCard = cloneDeep(selectedCard);
// if he clicks another item while an item is active
// or if he clicks the same item while active
// should just make it inactive
if (newSelectedCard !== null || newSelectedCard === id) {
setSelectedCard(null)
} else {
setSelectedCard(id)
}
console.debug(selectedCard, id)
}
return (
<ul className="card-list">
{cardData.map(card => (
<Card
onClick={() => onCardClick(card.id)}
key={card.id}
isSelected={selectedCard === card.id}
{...card}
/>
))}
</ul>
)
}
export const CardList = () => (
<List/>
);
从“/Card”导入{Card};
从“lodash/cloneDeep”导入cloneDeep;
常量列表=()=>{
const[selectedCard,setSelectedCard]=使用状态(空);
const onCardClick=id=>{
console.debug(选择的卡,id)
const newSelectedCard=cloneDeep(selectedCard);
//如果他在某个项目处于活动状态时单击另一个项目
//或者如果他在活动状态下单击同一项
//应该让它处于非活动状态
if(newSelectedCard!==null | | newSelectedCard===id){
设置所选卡(空)
}否则{
设置所选卡(id)
}
console.debug(选择的卡,id)
}
返回(
{cardData.map(卡=>(
onCardClick(card.id)}
密钥={card.id}
isSelected={selectedCard===card.id}
{…卡片}
/>
))}
)
}
导出常量卡片列表=()=>(
);
问题在于,2控制台.debugs
打印相同的值,这意味着状态不会立即更新,我在这里和那里遇到一些奇怪的行为。我这里遗漏了什么吗?不知道为什么需要使用cloneDeep
const onCardClick = id => {
if (selectedCard === id) {
setSelectedCard(null);
} else {
setSelectedCard(id);
}
}
基本上你需要遵循以下3个条件
if(newSelectedCard === null){
setSelectedCard(id)
}
else if(newSelectedCard === id){
setSelectedCard(null);
}
else{
setSelectedCard(id)
}
以下是完整的示例:
import cloneDeep from 'lodash/cloneDeep';
import React, {useState} from "react";
const List = () => {
const [cardData, setCardData] = useState([
{id: 1, title: 'First Card'},
{id: 2, title: 'Second Card'},
{id: 3, title: 'Third Card'},
{id: 4, title: 'Fourth Card'},
]);
const [selectedCard, setSelectedCard] = useState(null);
const onCardClick = id => {
console.log(selectedCard, id);
const newSelectedCard = cloneDeep(selectedCard);
// if he clicks another item while an item is active
// or if he clicks the same item while active
// should just make it inactive
if(newSelectedCard === null){
setSelectedCard(id)
}
else if(newSelectedCard === id){
setSelectedCard(null);
}
else{
setSelectedCard(id)
}
console.log(selectedCard, id)
};
return (
<ul className="card-list">
{cardData.map(card => (
<Card
onClick={() => onCardClick(card.id)}
key={card.id}
isSelected={selectedCard === card.id}
{...card}
/>
))}
</ul>
)
};
export const CardList = () => (
<List/>
);
const Card = (props) => {
const backColor = props.isSelected? '#F9740E' : '#3FB566';
return (
<div onClick={() => props.onClick()}>
<div style={{backgroundColor: backColor, border: '1px solid darkgreen', color: 'white', padding: 10, marginBottom: 10}}>
<h3>{props.id}</h3>
<h4>{props.title}</h4>
</div>
</div>
);
};
从“lodash/cloneDeep”导入cloneDeep;
从“React”导入React,{useState};
常量列表=()=>{
const[cardData,setCardData]=useState([
{id:1,标题:'第一张牌'},
{id:2,标题:'第二张卡'},
{id:3,标题:'第三张牌'},
{id:4,标题:'第四张牌'},
]);
const[selectedCard,setSelectedCard]=使用状态(空);
const onCardClick=id=>{
console.log(所选卡片,id);
const newSelectedCard=cloneDeep(selectedCard);
//如果他在某个项目处于活动状态时单击另一个项目
//或者如果他在活动状态下单击同一项
//应该让它处于非活动状态
if(newSelectedCard===null){
设置所选卡(id)
}
else if(newSelectedCard==id){
设置所选卡(空);
}
否则{
设置所选卡(id)
}
console.log(选择的卡,id)
};
返回(
{cardData.map(卡=>(
onCardClick(card.id)}
密钥={card.id}
isSelected={selectedCard===card.id}
{…卡片}
/>
))}
)
};
导出常量卡片列表=()=>(
);
康斯特卡=(道具)=>{
const backColor=props.isSelected?#F9740E':#3FB566';
返回(
props.onClick()}>
{props.id}
{props.title}
);
};
更新
我以前使用对象作为状态,但忘了删除它。尽管删除cloneDeep根本不会改变任何事情^^尝试使用设置前等待选择卡(id);没有什么变化。我想我应该以某种方式在useEffect中添加该函数,但无法理解正确的方法。嗨,它正在工作,请参阅我最后一个答案更新部分中的代码沙盒的链接。你是对的。虽然在我这方面,它仍然是控制台登录两个实例上的相同输出。如果我有什么不一样的地方,我需要在回家的时候重新检查一下。我不知道发生了什么。我评论了我的全部代码并添加了你的代码,但我仍然从两个控制台获得相同的打印。日志:嗨,我再次检查了我的代码沙箱,一切都很好。不知道你那边发生了什么。没有看到任何东西就很难辨认。请仔细检查你的代码。希望有问题。