当我单击单个字体超赞图标(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'
/>
);
}
它的工作方式与我上面所述的相同,但不像我想要的那样。
答案 0 :(得分:2)
有趣。问题是所有FontAwesomeIcons
共享同一个styles
对象。因此,如果颜色为true
,则所有图标都变为橙色。
您应该做的是将每个FontAwesomeIcon
移动到其自己的组件中,这样它就可以管理自己的颜色state
和样式对象。
这是一个有效的沙箱:https://codesandbox.io/s/billowing-frog-scci2
让我们考虑这个例子:
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,该子组件将该数组作为属性接受。
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
创建图标集合。代替直接使用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
组件中,我们将使用通过道具传递的图标来渲染FontAwesomeIcon
。请注意,每个MyIcon组件都管理自己的color state
和样式对象。
在FontAwesomeIcon
定义中,对于其onClick()
,我们执行状态更新函数,该函数作为prop(props.setSelectedIndex)传递,并为其赋予图标索引(属于该{{ 1}}组件。这样会更新父级的选定状态,该值会传回给MyIcon
进行评估。
因此,当您单击coffee-icon时,将MyIcon
转换为属于初始数组的图标的索引,该索引现在可以在selectedIndex
中读取。重新渲染MyIcon对象的所有实例,在每个实例中,我们检查MyIcon
对象是否匹配其自己的图标索引。如果是这样,我们将selected
更改为color-state
(橙色),否则,将其更改为true
(灰色)。
总而言之,只要您具有依赖于公共值的组件,就应考虑创建中介状态以帮助管理其功能。简而言之,这就是“父子”组件关系。
答案 1 :(得分:0)
鉴于您提供的代码段,在我看来FontAwesomeIcons
是某些父级组件的子级组件。在无法看到父组件的情况下,我将不得不假设您分别渲染每个组件。因此,当前每个组件都彼此独立运行。
要让组件知道一个组件何时为橙色,则意味着您需要与每个子组件共享相同的数据。我想到两种方法。
1)您可以使用redux。您想要做的事情有点笨重,但可以使用。
2)您通过父级传递的功能来控制按钮颜色的状态。在父级中添加一些逻辑,您将获得对按钮布局的更多控制。
例如在您的父组件中:
...
render() {
return (
<div>
<FontAwesomeIcons onClick(() => {make magic})/>
<FontAwesomeIcons onClick(() => {make magic})/>
...
</div>
)
}
这当然不是创建多个图标的最佳方法,但可以理解这一点。
答案 2 :(得分:0)
您可以在fontawesome图标上创建一个常用(可重用)组件,并且可以在任意位置使用n次, 签出demo
答案 3 :(得分:0)
您可以使用使用先前状态的切换功能,然后可以在单击事件上调用该功能以完成工作。不要忘记传递颜色代码。