当我单击单个字体超赞图标(6个图标中的1个)时,它会像应该的那样将颜色从灰色更改为橙​​色。我还想确保一次字体真棒图标只能是橙色。因此,如果我单击另一个图标,以前是橙色的图标现在变成灰色,而我刚刚单击的图标是橙色。我一直在努力做到这一点,任何提示将不胜感激。

import React, { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
export default function FontAwesomeIcons(props) {

  const [color, setColor] = useState(false);

  const styles = {
    display: "inline-flex",
    justifyContent: "center",
    margin: "10px",
    color: color ? "orange" : "gray",
    cursor: "pointer"
  };

  return (
    <FontAwesomeIcon
      onClick={() => setColor(!color)}
      style={styles}
      icon={props.name}
      size='2x'
    />
  );
}


它的工作方式与我上面所述的相同,但不像我想要的那样。

最佳答案

有趣。问题是所有FontAwesomeIcons共享同一个styles对象。因此,如果颜色为true,则所有图标将变为橙色。

您应该做的是将每个FontAwesomeIcon移动到其自己的组件中,这样它就可以管理自己的颜色state和样式对象。

这是一个有效的沙箱:https://codesandbox.io/s/billowing-frog-scci2

让我们考虑这个例子:

App.js

import React from "react";
import FontAwesomeIcons from "./FontAwesomeIcons";
import { faCoffee, faUser, faTrash } from "@fortawesome/free-solid-svg-icons";

import ReactDOM from "react-dom";

import "./styles.css";
const icons = [faCoffee, faUser, faTrash];

const App = () => {
  return (
    <div>
      <h4>Choose Food</h4>
      <FontAwesomeIcons icons={icons} />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement)


在最高级的组件中,我们导入要使用的超棒字体图标,并将它们放在称为图标的数组中。

我们将这些图标传递给子组件FontAwesomeIcons,该子组件接受该数组作为属性。

FontAwesomeIcons.js

import React, { useState } from "react";
import MyIcon from "./MyIcon";
const FontAwesomeIcons = props => {
  const [selectedIndex, setSelectedIndex] = useState({});

  const createIcons = () => {
    const { icons } = props;
    return icons.map((icon, iconIndex) => {
      return (
        <MyIcon
          thisIcon={icon}
          selectedIndex={selectedIndex}
          iconIndex={iconIndex}
          setSelectedIndex={setSelectedIndex}
          size="2x"
        />
      );
    });
  };
  return createIcons();
};

export default FontAwesomeIcons;


FontAwesomeIcons中,我们使用该icons道具,然后在其上方使用iterate创建图标集合。我们将直接将数组中的每个FontAwesomeIcon传递给我们自己的icon组件的新实例,而不是直接使用font-awesome提供的MyIcon组件。

此外,我们将跟踪selectedIndex状态,以确定单击了哪个图标。 SelectedIndex及其更新程序功能也作为道具传递给MyIcon,这对于更新样式对象至关重要。

MyIcon.js

import React, { useState, useEffect } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const MyIcon = props => {
  const [color, setColor] = useState(false);

  useEffect(() => {
    if (props.selectedIndex === props.iconIndex) {
      setColor(true);
    } else {
      setColor(false);
    }
  }, [props.selectedIndex]);

  const styles = {
    display: "inline-flex",
    justifyContent: "center",
    margin: "10px",
    color: color ? "orange" : "gray",
    cursor: "pointer"
  };

  return (
    <div>
      <FontAwesomeIcon
        onClick={() => props.setSelectedIndex(props.iconIndex)}
        style={styles}
        icon={props.thisIcon}
        size="2x"
      />
    </div>
  );
};

export default MyIcon;


最后,在我们的自定义MyIcon组件中,我们将使用通过道具传递的图标来渲染FontAwesomeIcon。请注意,每个MyIcon组件都管理自己的color state和样式对象。

FontAwesomeIcon定义中,对于其onClick(),我们执行状态更新功能,该功能作为prop(props.setSelectedIndex)传递,并为其提供属于该MyIcon组件的图标索引。这将更新父级的选定状态,并且该值将传回给MyIcon进行评估。

因此,当您单击coffee-icon时,将selectedIndex变为属于初始数组的图标的索引,该索引现在在MyIcon中可读。重新渲染MyIcon对象的所有实例,在每个实例中,我们检查selected对象是否匹配其自己的icon-index。如果是这样,我们将color-state更改为true(橙色),否则,将其更改为false(灰色)。

总之,只要您具有依赖于公共值的组件,就应考虑创建一个中间状态来帮助管理其功能。简而言之,这就是“父子”组件关系。

关于javascript - 如何在onClick事件期间更改React中多个元素的状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57086729/

10-11 11:57