簡體   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