javascript - React Hooks,有条件地改变 onClick 函数内的状态,在下次点击时更新

标签 javascript reactjs react-hooks

你好,我有一个列表组件,它呈现一些 <Card>具有 prop 的组件isSelected .因为当 <Card> 时会发生很多事情组件有 isSelected === true我添加了 state<List> 上组件,我希望当有人点击卡片进行检查时:

1) 如果没有以前选择的项目(state===null 将该项目的 id 添加到状态)

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/>
);

问题是 2 console.debugs打印相同的值,这意味着状态不会立即更新,并且我时不时遇到一些奇怪的行为。我在这里遗漏了什么吗?

最佳答案

基本上你需要遵循以下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>
    );
};

更新 Here is Code SandBox

关于javascript - React Hooks,有条件地改变 onClick 函数内的状态,在下次点击时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62139070/

相关文章:

javascript - 平滑滚动到 View vanilla javascript

javascript - 对 jQuery 加载的 div 中的 li 进行排序

javascript - 如何使用 useState Hook 更新对象的状态并保留现有元素?

javascript - React 从组件外部的函数调用中设置 Hook

javascript - Rails 应用程序中的 JQuery 插件 lightbox_me

reactjs - 如何使用 TypeScript 验证与 Axios GET 响应的接口(interface)

reactjs - IndexRoute 似乎不起作用

reactjs - “react-dnd”不包含名为 'DragDropContext' 的导出

reactjs - 在 Typescript 中使用 useContext 传递状态

javascript - 使用 Node JS 从浏览器的用户输入中检索 twitter