【问题标题】:How to show only one active item at a time with react and material ui如何使用反应和材料 ui 一次仅显示一个活动项目
【发布时间】:2021-08-10 07:40:14
【问题描述】:

我正在开发一个应用程序,现在我需要在单击按钮时将一个活动类添加到我正在显示的卡片中。

到目前为止,我在单击时获得了卡片的索引。 单击后,所需的卡片将更改其背景颜色。 但是,当我单击另一个按钮时,前一张卡片仍然处于活动状态并具有相同的颜色。我想一次只显示一张有效的卡片。

import React, { Fragment } from "react";
// MUI
import { Container, Grid } from "@material-ui/core";
import { Switch, Route, useRouteMatch } from "react-router-dom";
// Components
import DayCardItem from "./DayCardItem";
import Carousel from "./Carousel";

const DayCard = (props) => {
      <div
        style={{
          maxWidth: 1200,
          marginLeft: "auto",
          marginRight: "auto",
          marginTop: 64,
        }}
      >
        <Carousel show={3}>
          {dailyData &&
            dailyData.map((day, index) => (
              <DayCardItem key={index} day={day} cardIndex={index} />
            ))}
        </Carousel>
      </div>
    </Fragment>
  );
};
export default DayCard;

import React, { useEffect, useState } from "react";
import moment from "moment";
import { Link, useRouteMatch } from "react-router-dom";
// MUI
import { Button, Typography } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
//Redux
import { useSelector } from "react-redux";

const useStyles = makeStyles((theme) => ({
  cardItem: {
    backgroundColor: "#ffffff",
  },
  activeCardItem: {
    color: "#364150",
    backgroundColor: "#efefef"
  },
}));

const DayCardItem = (props) => {
  const { day, cardIndex } = props;

  const classes = useStyles();

  let [activeItem, setActiveItem] = useState(null);


  const handleActiveCard = (cardId) => {
    let actualCardId = activeItem;
    actualCardId = cardId;
    setActiveItem(actualCardId);
    };

  return (
    <div className={`${cardIndex === activeItem && classes.activeCardItem}`}>
      <Link to={`${url}/${paramUrlId}`}>
        <Button
          variant="contained"
          color="primary"
          onClick={() => handleActiveCard(cardIndex)}
        >
          Weather Details
        </Button>
      </Link>
    </div>
  );
};

export default DayCardItem;

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    您需要将状态移动到其父级

    import React, { Fragment } from "react";
    // MUI
    import { Container, Grid } from "@material-ui/core";
    import { Switch, Route, useRouteMatch } from "react-router-dom";
    // Components
    import DayCardItem from "./DayCardItem";
    import Carousel from "./Carousel";
    
    const DayCard = (props) => {
    let [activeItem, setActiveItem] = useState(null);
    return(
          <div
            style={{
              maxWidth: 1200,
              marginLeft: "auto",
              marginRight: "auto",
              marginTop: 64,
            }}
          >
            <Carousel show={3}>
              {dailyData &&
                dailyData.map((day, index) => (
                  <DayCardItem 
                      key={index} 
                      day={day} 
                      cardIndex={index} 
                      activeItem={activeItem} 
                      setActiveItem={setActiveItem}
                   />
                ))}
            </Carousel>
          </div>
        </Fragment>
      );
    };
    export default DayCard;
    

    DayCardItem.js

    import React, { useEffect, useState } from "react";
    import moment from "moment";
    import { Link, useRouteMatch } from "react-router-dom";
    // MUI
    import { Button, Typography } from "@material-ui/core";
    import { makeStyles } from "@material-ui/core/styles";
    //Redux
    import { useSelector } from "react-redux";
    
    const useStyles = makeStyles((theme) => ({
      cardItem: {
        backgroundColor: "#ffffff",
      },
      activeCardItem: {
        color: "#364150",
        backgroundColor: "#efefef"
      },
    }));
    
    const DayCardItem = (props) => {
    
      const { day, cardIndex } = props;
      const { activeItem, setActiveItem } = props;
      const classes = useStyles();
    
    
      const handleActiveCard = (cardId) => {
        let actualCardId = cardId;
        setActiveItem(actualCardId);
        };
    
      return (
        <div className={`${cardIndex === activeItem && classes.activeCardItem}`}>
          <Link to={`${url}/${paramUrlId}`}>
            <Button
              variant="contained"
              color="primary"
              onClick={() => handleActiveCard(cardIndex)}
            >
              Weather Details
            </Button>
          </Link>
        </div>
      );
    };
    
    export default DayCardItem;
    

    这应该可以解决您的问题,基本上是因为您在 DayCardItem 内创建活动状态,因此它特定于每个项目,如果您将其转移到 DayCard,那么所有项目都将是通用的,这是您对此用途的要求案例。

    提示:不要将索引用作键

    【讨论】:

      【解决方案2】:

      每个DayCardItem 组件都有自己的活动状态,因此它们都不知道有任何其他活动项目可以自行停用。这里的一个解决方案是将activeItem 状态提升到父级,并且一次只跟踪一个活动项。

      const DayCard = (props) => {
        const [activeIndex, setActiveIndex] = useState(null);
      
        // set new index if different, otherwise set back to null to deactivate
        const handleActiveCard = (index) => {
          setActiveIndex(activeIndex => activeIndex === index ? null : index);
        }; 
      
        ...
      
            <div
              style={{
                maxWidth: 1200,
                marginLeft: "auto",
                marginRight: "auto",
                marginTop: 64,
              }}
            >
              <Carousel show={3}>
                {dailyData &&
                  dailyData.map((day, index) => (
                    <DayCardItem
                      key={index}
                      day={day}
                      setActive={setActiveIndex} // <-- pass callback
                      isActive={activeIndex === index} // <-- compute if active
                    />
                  ))}
              </Carousel>
            </div>
          </Fragment>
        );
      };
      
      const DayCardItem = ({ day, isActive, setActive }) => {
        const classes = useStyles();
      
        return (
          <div className={`${isActive && classes.activeCardItem}`}>
            <Link to={`${url}/${paramUrlId}`}>
              <Button
                variant="contained"
                color="primary"
                onClick={() => setActive(cardIndex)}
              >
                Weather Details
              </Button>
            </Link>
          </div>
        );
      };
      

      【讨论】:

        猜你喜欢
        • 2019-01-19
        • 2019-01-27
        • 2023-01-24
        • 2021-09-12
        • 2017-01-14
        • 1970-01-01
        • 1970-01-01
        • 2019-10-10
        • 1970-01-01
        相关资源
        最近更新 更多