使用 React 和 map 时如何只折叠一个 div [英] How to Collapse only one div when using React and map

查看:58
本文介绍了使用 React 和 map 时如何只折叠一个 div的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 React 创建一个动态菜单,但我正在努力实现折叠功能.我首先使用一个工作正常的 Json 对象映射每个 MenuItem.之后,当我尝试在单击时实现折叠功能时,所有菜单项都会折叠,而不仅仅是被单击的菜单项.我尝试实现一个在真/假之间切换的数组,但在单击时无法访问该值.代码如下:

import React, { Component } from "react";从样式组件"导入样式;导入./sidebar.css";从反应引导/折叠"导入折叠const 仪表板项目 = [{编号:1,title: "仪表盘",字幕:[分析"、监控"、工作场所"]、文字:Anim pariatur cliche reprehenderit,enim eiusmod high life accusamus terry richardson ad squid.Nihil anim keffiyeh helvetica,精酿啤酒labore wes anderson cred nesciunt sapiente ea proident."},{编号:2,title: "表格",字幕:[基本形式"、步骤形式"、高级形式"]、文字:enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica,craft beerlabore wes anderson cred nesciunt sapiente ea proident."},{编号:3,title: "列表",字幕:[搜索表"、基本列表"、卡片列表"]、文字:理查森广告鱿鱼.Nihil anim keffiyeh helvetica,精酿啤酒labore wes anderson cred nesciunt sapiente ea proident."},{编号:4,title: "个人资料",字幕:[基本资料"、高级资料"]、文字:Nihil anim keffiyeh helvetica,精酿啤酒,wes anderson cred nesciunt sapiente ea proident."},{编号:5,title: "结果",字幕:[成功",失败"],文字:精酿啤酒,韦斯·安德森 (wes anderson) 信用 nesciunt sapiente ea proident."},{编号:6,title: "账户",字幕:[账户中心"、账户设置"]、文字:wes anderson cred nesciunt sapiente ea proident."}];功能侧边栏(){const [open, setOpen] = React.useState(false);const [clickedItems, setClickedItems] = React.useState( [false, false, false, false, false, false] );函数 handleClick(id) {console.log("" + id + " 处的初始值是 " + clickedItems[id - 1] + " 数组是 " + clickedItems)clickedItems[id - 1] = !clickedItems[id - 1];console.log(clickedItems);设置打开(!打开)}返回 (<侧边栏容器><侧边栏菜单><菜单标志>仪表盘</MenuLogo>{dashboardItems.map((postData) => {返回(<div 键 = {postData.id} ><侧边栏菜单项onClick={() =>处理点击(postData.id)}><SidebarMenuItemLabel>{postData.title}</SidebarMenuItemLabel></SidebarMenuItem><Collapse in={open}>a <div key={postData.id} id="example-collapse-text" className="collapsedText">{postData.text}

</收起>

);})}</SidebarMenu></SidebarContainer>);}const SidebarContainer = styled.div`高度:100vh;宽度:270px;背景颜色:#252529;颜色:#fff;显示:弹性;弹性方向:列;字体系列:Roboto",无衬线;`;const SidebarMenu = styled.ul`显示:弹性;对齐项目:左;弹性方向:列;列表样式:无;宽度:100%;填充左:0px;`;const MenuLogo = styled.div`显示:弹性;对齐项目:居中;对齐内容:开始;间隙:16px;字体大小:18px;行高:1.5;字体粗细:600;高度:45px;颜色:#fff;边距:30px 30px 30px 30px;填充底部:20px;边框底部:1px 实心 #2e2e33;`;const SidebarMenuItem = styled.li`显示:弹性;高度:40px;宽度:100%;对齐项目:居中;padding-left: 30px;&:悬停{背景:rgba(255, 255, 255, 0.05);框阴影:插入 3px 0 0 0 #ffffff;光标:指针;}`;const SidebarMenuItemLabel = styled.p`font-family: "Open Sans", sans-serif;颜色:#fff;字体大小:16px;字体粗细:600;行高:1.3;文本对齐:左;填充:15px 0px;左边距:15px;边距顶部:15px;颜色:#ffffff;`;导出默认侧边栏;

如果您知道解决方案,请告诉我.谢谢!

解决方案

你的open"变量应该是一个空对象.

const [open, setOpen] = React.useState({});

然后在 handleClick 函数上创建一个以id"为键的新字段.

function handleClick(id) {setOpen((prevState => ({...prevState, [id]: !prevState[id]}))}

然后将其用作打开"道具.

<Collapse in={open[postData.id]}><div key={postData.id} id="example-collapse-text" className="collapsedText">{postData.text}

</收起>

请记住,当您想要访问实际状态时,您总是希望这样做:

const [state, setState] = useState(true)setState(prevState => !prevState)

从来没有

const [state, setState] = useState(true)setState(!state)//<-- 这很糟糕

I'm trying to create a dynamic menu using React and I'm struggling to implement the collapse functionality. I start by mapping each MenuItem using a Json object which works fine. Afterwards, when I tried to implement a collapse functionality when clicked on, all the menuitems collapse instead of just the one that is clicked on. I tried implementing an array which toggles between true/false but I'm having trouble accessing the value when clicked upon. Here is the code:

import React, { Component } from "react";
import styled from "styled-components";
import "./sidebar.css";
import Collapse from 'react-bootstrap/Collapse'
const dashboardItems = [
    {
        id: 1,
        title: "Dashboard",
        subtitles: ["Analysis", "Monitor", "Workpplace"],
        text: "Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident."
    },
    {
        id: 2,
        title: "Form",
        subtitles: ["Basic Form", "Step Form", "Advanced Form"],
        text: "enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident."

    },
    {
        id: 3,
        title: "List",
        subtitles: ["Search Table", "Basic List", "Card List"],
        text: "richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident."
    },
    {
        id: 4,
        title: "Profile",
        subtitles: ["Basic Profile", "Advanced Profile"],
        text: "Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident."
    },
    {
        id: 5,
        title: "Result",
        subtitles: ["Success", "Failure"],
        text: "craft beer labore wes anderson cred nesciunt sapiente ea proident."
    },
    {
        id: 6,
        title: "Account",
        subtitles: ["Account Center", "Account Settings"],
        text: "wes anderson cred nesciunt sapiente ea proident."
    }
];


function Sidebar(){
        const [open, setOpen] = React.useState(false);
        const [clickedItems, setClickedItems] = React.useState( [false, false, false, false, false, false] );
        function handleClick(id) {
            console.log("initial value at " + id + " is " + clickedItems[id - 1] + " array is " + clickedItems)
            clickedItems[id - 1] = !clickedItems[id - 1];
            console.log(clickedItems);
            setOpen(!open)
        }

        return (
           <SidebarContainer>
               <SidebarMenu>
                   <MenuLogo>
                   Dashboard
                   </MenuLogo>                

                    {dashboardItems.map((postData) => {
                        return(
                            <div key = {postData.id} >
                                <SidebarMenuItem 
                                    onClick={() => handleClick(postData.id)}
                                >
                                        <SidebarMenuItemLabel>{postData.title}</SidebarMenuItemLabel>
                                </SidebarMenuItem>
                                <Collapse in={open}>
a                                    <div key={postData.id} id="example-collapse-text" className="collapsedText">
                                        {postData.text}
                                    </div>
                                </Collapse>
                           </div>
                        );
                    })}
                </SidebarMenu>
            </SidebarContainer>
        );
}


const SidebarContainer = styled.div`
        height: 100vh;
        width: 270px;
        background-color: #252529;
        color: #fff;
        display: flex;
        flex-direction: column;
        font-family: "Roboto", sans-serif;
`;

const SidebarMenu = styled.ul`
        display: flex;
        align-items: left;
        flex-direction: column;
        list-style: none;
        width: 100%;
        padding-left: 0px;
`;

const MenuLogo = styled.div`
        display: flex;
        align-items: center;
        justify-content: start;
        gap: 16px;
        font-size: 18px;
        line-height: 1.5;
        font-weight: 600;
        height: 45px;
        color: #fff;
        margin: 30px 30px 30px 30px;
        padding-bottom: 20px;
        border-bottom: 1px solid #2e2e33;
`;

const SidebarMenuItem = styled.li`
        display: flex;
        height: 40px;
        width: 100%;
        align-items: center;
        padding-left: 30px;
        &:hover {
        background: rgba(255, 255, 255, 0.05);
        box-shadow: inset 3px 0 0 0 #ffffff;
        cursor: pointer;
}
`;

const SidebarMenuItemLabel = styled.p`
        font-family: "Open Sans", sans-serif;
        color: #fff;
        font-size: 16px;
        font-weight: 600;
        line-height: 1.3;
        text-align: left;
        padding: 15px 0px;
        margin-left: 15px;
        margin-top: 15px;
        color: #ffffff;
`;


export default Sidebar;

Please let me know if you might know of a solution. Thanks!

解决方案

Your "open" variable should be an empty object.


const [open, setOpen] = React.useState({});

Then on the handleClick function you create a new field that has "id" as key.

function handleClick(id) {
            setOpen((prevState => ({...prevState, [id]: !prevState[id]}))
        }

Then use that as the "open" prop.


 <Collapse in={open[postData.id]}>
  <div key={postData.id} id="example-collapse-text" className="collapsedText">
    {postData.text}
  </div>
 </Collapse>

Keep in mind that when you want to access the actual state, you always want to do this:

const [state, setState] = useState(true)
setState(prevState => !prevState)

And never

const [state, setState] = useState(true)
setState(!state) // <-- THIS IS BAD

这篇关于使用 React 和 map 时如何只折叠一个 div的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆