繁体   English   中英

如何在 onClick 事件期间更改 React 中多个元素的状态

[英]How to change state on multiple elements in React during onClick event

当我单击单个字体真棒图标(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对象。 因此,如果 color 为true ,则所有图标都变为橙色。

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

这是一个工作沙箱: https : //codesandbox.io/s/billowing-frog-scci2

让我们考虑这个例子:

应用程序.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)

在最上层的组件中,我们导入我们想要使用的字体很棒的图标,并将它们放在一个名为 icons 的数组中。

我们将这些图标传递给我们的子组件 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 FontAwesomeIcons ,并对其iterate以创建图标集合。 我们不会直接使用 font-awesome 提供的FontAwesomeIcon组件,而是将数组中的每个icon传递给我们自己的MyIcon组件的新实例。

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

我的图标

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组件中,我们将使用通过 props 传递的图标呈现FontAwesomeIcon 请注意,每个 MyIcon 组件管理自己的color state和样式对象。

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

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

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

鉴于您提供的代码片段,在我看来FontAwesomeIcons是某个父组件的子组件。 在无法看到父组件的情况下,我将不得不假设您正在分别渲染每个组件。 因此,每个组件当前都彼此独立运行。

要让组件知道一个组件何时为橙色,这意味着您需要与每个子组件共享相同的数据。 想到了两种方法。

1)您可以使用redux。 对于您正在尝试做的事情来说有点笨重,但它会起作用。

2)您从父级传递一个函数,该函数控制按钮的颜色状态。 在父级中添加一些逻辑,您将获得对按钮布局的更多控制。

例如在您的父组件中:

...
render() {
 return (
   <div>
     <FontAwesomeIcons onClick(() => {make magic})/>
     <FontAwesomeIcons onClick(() => {make magic})/>
      ...
   </div>
 )
}

这当然不是创建多个图标的最佳方式,但它可以说明问题。

您可以创建 fontawesome 图标的一个通用(可重用)组件,并且可以在任何地方使用它 n 次,请查看此演示

您可以使用使用先前状态的切换函数,然后您可以在单击事件时调用该函数来完成这项工作。 不要忘记传递颜色代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM