【问题标题】:How to set the active element in a list using javascript and react?如何使用javascript在列表中设置活动元素并做出反应?
【发布时间】:2020-08-19 12:04:56
【问题描述】:

我有一个项目列表,单击一个 item1 应该使其中的 addbutton 处于活动状态(添加背景颜色为红色)并单击其他项目说 item2 应该使其中的 addbutton 处于活动状态(添加背景颜色为红色)并且 item1 处于非活动状态。

下面是我的代码,

function Parent () {
    return (
        <AddButton />//used here not considering about active index
        <List items={items}/>
    );
}
        
function List({items}: Props) {
    return (
        {Items.map((item: any) => {
            return(
                <Card>
                    <Header> title</Header>
                    <AddButton /> //want to make this active meaning add backgroundcolor red
                </Card>
            )
        }
    )
}

const useDrawing = (item) => {
    const [isToolActive, setIsToolActive] = React.useState(false);
    const [saveableDrawing, setSaveableDrawing,
  ] = React.useState<google.maps.Drawing | null>(null);
    const isDrawing = isToolActive || saveableDrawing;
    const toggleDrawing = React.useCallback(async () => {
        if (isDrawing) {
            cancelDrawing(); //this will set isToolActive to false
        } else {
            setIsToolActive(true);
        }
    }, [isDrawing, cancelDrawing]);
    return {toggleDrawing, isDrawing};
}

function AddButton ({item}: Props) {
    const {isDrawing, toggleDrawing} = useDrawing(item);
    return (
        <IconButton
            onClick={toggleDrawing}
            active={isDrawing}
        />
    );
}

function IconButton ({active}: Props) {
    return (
        <wrapper $active={active}>
    );
}

const Wrapper = styled.button<{
    $active: boolean;
}>`

    ${props =>
        props.$active &&
            css`
                background-color: red;
            `}
 `;

上面的代码有效。但问题是单击列表中的一项说 item1 添加背景颜色红色以添加按钮。如果用户单击列表中的另一个项目说 item2,那么它还会添加背景颜色红色以添加 item2 的按钮。

我希望当用户点击 item2 时 item1 addbutton 不应该有红色的背景颜色。只有列表添加按钮中最近单击的项目的背景颜色应为红色。

我怎样才能修复我上面的代码。有人可以帮我解决这个问题。谢谢。

编辑

我已经尝试过这样的事情......

function List() {
    const [activeIndex, setActiveIndex] = React.useState(null);
    const handleClick = (itemId: any) => {
         setActiveIndex(itemId);
    }
    return (
        {Items.map((item: any, index: number) => {
            return(
                <Card>
                    <Header> title</Header>
                    <AddButton handleClick={handleClick}  isActive={activeIndex === index} /> //want to make this active meaning add backgroundcolor red
                </Card>
            )
        }
    )
}


function AddButton ({item,index, handleClick, isActive}: Props) {
    const {isDrawing, toggleDrawing} = useDrawing(item);
    const anotherClick = ()  = >{
        handleClick(index);
        toggleDrawing();
    }
    return (
        <IconButton
            onClick={AnotherClick}
            active={isDrawing && isActive}
        />
    );
}

这可行,但是当用户单击 item1 时,item1 添加按钮具有背景色,而当单击 item2 两次时,只有 item2 的添加按钮具有背景色。

我不确定是什么原因造成的。有人可以帮我解决这个问题。谢谢。

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    您必须将激活按钮的逻辑上移一层,到List 组件。在那里,您必须跟踪当前处于活动状态的按钮:

    function List() {
        const [activeButtonIndex, setActiveIndex] = React.useState();
        return (
            {Items.map((item: any, index: number) => {
                return(
                    <Card>
                        <Header> title</Header>
                        <AddButton isToolActive={activeButtonIndex === index} index={index} setActiveIndex={setActiveIndex} /> //want to make this active meaning add backgroundcolor red
                    </Card>
                )
            }
        )
    }
    
    const useDrawing = (item, index, isToolActive, setActiveIndex) => {
        
        const isDrawing = isToolActive;
        toggleDrawing= () => {
            if (isToolActive) {
                setActiveIndex(undefined);
            }
            setActiveIndex(index);
        }
        return {toggleDrawing, isDrawing};
    }
    
    function AddButton ({item, index, isActive, setActiveIndex}: Props) {
        const {isDrawing, toggleDrawing} = useDrawing(item, index, isToolActive, setActiveIndex);
        return (
            <IconButton
                onClick={toggleDrawing}
                active={isDrawing}
            />
        );
    }
    
    function IconButton ({active}: Props) {
        return (
            <wrapper $active={active}>
        );
    }
    
    const Wrapper = styled.button<{
        $active: boolean;
    }>`
    
        ${props =>
            props.$active &&
                css`
                    background-color: red;
                `}
     `;

    【讨论】:

    • 谢谢。抱歉,我将编辑我的问题。不知何故不适用于我的代码。应提供完整的代码。
    • @saritha 在你的代码中你有active={isDrawing &amp;&amp; isActive} 但isActive={activeIndex} 所以只要activeIndex 是一个非零数字,isActive 总是真实的。
    • 我现在更改了 isActive={activeIndex === index} 并且仍然相同。第三次点击。不激活任何列表项。第四次有效。
    • 如果我将 AddButton 中的 active={isDrawing && isActive} 更改为 active={isActive},效果会很好。不知道这里出了什么问题。
    【解决方案2】:

    您可以将点击项的索引设置为状态,并从状态中检查与存储在状态中的列表项的索引是否使其处于活动状态。

     function List() {
        const [activeIndex, setActiveIndex] = React.useState(null);
        const handleClick = (key: number) => {
             setActiveIndex(key);
        }
        return (
            {Items.map((item: any, key: number) => {
                return(
                    <Card>
                        <Header> title</Header>
                        <AddButton handleClick={() => handleClick(key)} **isActive={key ==activeIndex}** />
                    </Card>
                )
            }
        )
    }
    
    
    function AddButton ({ handleClick, isActive}: Props) {
        const anotherClick = ()  = >{
            handleClick();
        }
        return (
            <IconButton
                onClick={AnotherClick}
                active={isActive}
            />
        );
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2020-03-27
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      相关资源
      最近更新 更多