Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React钩子,有条件地更改onClick函数内的状态,在下一次单击时更新_Javascript_Reactjs_React Hooks - Fatal编程技术网

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中添加该函数,但无法理解正确的方法。嗨,它正在工作,请参阅我最后一个答案更新部分中的
代码沙盒的链接。你是对的。虽然在我这方面,它仍然是控制台登录两个实例上的相同输出。如果我有什么不一样的地方,我需要在回家的时候重新检查一下。我不知道发生了什么。我评论了我的全部代码并添加了你的代码,但我仍然从两个控制台获得相同的打印。日志:嗨,我再次检查了我的代码沙箱,一切都很好。不知道你那边发生了什么。没有看到任何东西就很难辨认。请仔细检查你的代码。希望有问题。