【问题标题】:How to dynamically change CSS/highlight button elements based on filtered data in React JS?如何根据 React JS 中的过滤数据动态更改 CSS/突出显示按钮元素?
【发布时间】:2020-05-20 08:58:06
【问题描述】:

我有一个由大量按钮(超过 300 个)组成的 UI,这些按钮根据 CSS 样式表设置样式。

如何根据传递的数据突出显示其中一些按钮。

例如,这是我拥有的一些按钮。它们都有一个分配给它们的唯一值,允许用户在单击时提取更多信息(因此是 onClick)。

<div className="btn">
   <button type = "button" name = "channelID" value = 'A01' onClick = {this.onClick}>A01</button>
   <button type = "button" name = "channelID" value = 'A02' onClick = {this.onClick}>A02</button>
   <button type = "button" name = "channelID" value = 'A03' onClick = {this.onClick}>A03</button>
   <button type = "button" name = "channelID" value = 'A04' onClick = {this.onClick}>A04</button>
   <button type = "button" name = "channelID" value = 'A05' onClick = {this.onClick}>A05</button>
</div>

默认情况下,假设 CSS 样式表设置按钮的样式如下:

.btn button = {
   background-color: black;
   color: white
}

我还有一个选择标签,它应该允许用户选择频道的特定属性:

<select name="datatype" onChange={this.handleChange}>
   <option>--- Data Type ---</option>
   <option value="inspected">View Inspected Channels</option>
   <option value="requiresReplacement">View Channels to Replace</option>
</select>

假设有人从此下拉列表中选择了“已检查”。 它将仅从主数据中过滤并返回已检查属性设置为 true 的通道。如果只检查了通道 A02、A03 和 A05,它看起来像这样:

state = { 
   channelsToHighlight = [
      { 
         channelID: "A02",
         inspected: true
      }, 
      { 
         channelID: "A03",
         inspected: true
      }, 
      { 
         channelID: "A05",
         inspected: true
      }, 
   ]
}

(如果用户选择了“查看要替换的频道”选项,它将调出不同的频道子集。)

我现在希望通道 A02、A03 和 A05 具有不同的背景颜色,以便突出显示。

我考虑过向我的组件添加一个 getStyle() 选项,该选项将有条件地呈现,但我不确定我将如何做到这一点。是否可以将 channelsToHighlight 对象中的 channelID 属性与我为每个按钮设置的值匹配?

任何帮助或建议将不胜感激!

【问题讨论】:

  • 你可以有另一个 css 类,例如.selected-btn 具有您需要的 css 属性(即不同的颜色背景),您可以使用当前状态来确定是否在按钮上设置 className 以包含 selected-btn 类
  • 假设状态与您的按钮在同一个组件中,这可以通过以下方式确定:this.state.channelsToHighlight.find(c =&gt; c.channelID == "A02").inspected - for "A02"
  • 如何渲染按钮?是通过循环mapforEachfilter

标签: javascript css reactjs button


【解决方案1】:

假设您的按钮在map() 函数中呈现,我建议您制作一个&lt;Button /&gt; 组件,该组件将接收与其相关的状态项作为道具。然后,您可以轻松地执行以下操作之一。
内联样式:

<button style={{ backgroundColor: state.channelsToHighlight.inspected ? 'black' : 'white' }}></button>

或者您可以根据状态切换 CSS 类:

<button className={state.channelsToHighlight.inspected ? 'selected' : 'unselected'}></button>

如果您手动输入所有按钮,除非您有充分的理由,否则您应该考虑遍历数组并使用 JSX 中的 map 函数进行渲染。

希望这会有所帮助。祝你好运!

【讨论】:

  • 这不起作用,因为this.state.channelsToHighlight 是一个数组,您需要更像这样:this.state.channelsToHighlight.find(c =&gt; c.channelID == "A02").inspected 并更改每个按钮的通道 ID - 如果查找失败,您也会收到错误要在 channelsToHighlight 中找到通道,因此要么必须将它们的状态设为 false,要么添加额外的逻辑
  • 使用:this.state.channelsToHighlight.find(c =&gt; c.channelID == "A02")?.inspected
  • 谢谢!出于某种原因,我假设他正在渲染 map 函数中的元素......然后很容易获取和使用每个按钮的状态。我更新了我的答案
【解决方案2】:

首先为您希望所选按钮具有的样式添加 CSS:

.selected-button = {
   background-color: yellow;
   color: black
}

然后在您的渲染中,进入您的状态(假设状态在相同的组件中,否则进入道具)以获取此按钮的 inspected 的当前值,如果检查为真,则将 selected-button 类添加到特定按钮。

<div className="btn">
   <button className={this.state.channelsToHighlight.find(c => c.channelID == "A01")?.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = 'A01' onClick = {this.onClick}>A01</button>
   <button className={this.state.channelsToHighlight.find(c => c.channelID == "A02")?.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = 'A02' onClick = {this.onClick}>A02</button>
   <button className={this.state.channelsToHighlight.find(c => c.channelID == "A03")?.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = 'A03' onClick = {this.onClick}>A03</button>
   <button className={this.state.channelsToHighlight.find(c => c.channelID == "A04")?.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = 'A04' onClick = {this.onClick}>A04</button>
   <button className={this.state.channelsToHighlight.find(c => c.channelID == "A05")?.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = 'A05' onClick = {this.onClick}>A05</button>
</div>

旁注:您的按钮生成遵循每个按钮的相同模式,只是值和文本发生变化。您可以使用地图功能清理它。目前尚不清楚这是否只是一个示例 - 或者实际上是您项目中的代码,但这里有一个示例,说明如何使用您发布的代码执行此操作。这也将大大提高性能,因为 find 调用被删除,如果你有很多按钮,查找会很慢。使用地图可以解决这个问题。

首先重构您的状态,让每个按钮都有一个条目。

state = { 
   channels = [
      { 
         channelID: "A01",
         inspected: false
      }, 
      { 
         channelID: "A02",
         inspected: true
      }, 
      { 
         channelID: "A03",
         inspected: true
      }, 
      { 
         channelID: "A04",
         inspected: false
      }, 
      { 
         channelID: "A05",
         inspected: true
      }, 
   ]
}

然后将渲染更改为使用地图

<div className="btn">
  { 
      this.state.channels.map(ch => <button className={ch.inspected ? "selected-button" : ""} type = "button" name = "channelID" value = {ch.channelID} onClick = {this.onClick}>{ch.channelID}</button>)
  }
</div>

【讨论】:

    【解决方案3】:

    你能检查一下这个例子吗?希望对你有帮助。

    import React from "react";
    import Button from "@material-ui/core/Button";
    
    export default class HighlightButton extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                color: "primary",
                channels: [
                    {channelID: "A01", inspected: false},
                    {channelID: "A02", inspected: true},
                    {channelID: "A03", inspected: true},
                    {channelID: "A04", inspected: false},
                    {channelID: "A05", inspected: true},
                ],
                channelsToHighlight: [],
                channelsToNonHighlight: []
            }
        }
    
        handleChange = (event) => {
            let value = event.target.value;
            this.setState(prevState => {
                let chans = prevState.channels.filter(ch => ch.inspected === (value === "inspected"));
                return {channelsToHighlight: chans}
            })
            this.setState(prevState => {
                let chans = prevState.channels.filter(ch => ch.inspected === (value === "requiresReplacement"));
                return {channelsToNonHighlight: chans}
            })
        };
        onClick = () => {
    
        };
    
        render() {
            return (
                <div>
                    <select name="datatype" onChange={this.handleChange}>
                        <option>--- Data Type ---</option>
                        <option value="inspected">View Inspected Channels</option>
                        <option value="requiresReplacement">View Channels to Replace</option>
                    </select>
                    <div className="btn">
                        {
                            this.state.channelsToHighlight.map((channel, index) =>
                                <Button key={index} name={channel.channelID} value={channel.channelID}
                                        onClick={this.onClick} variant="contained"
                                        color={channel.inspected ? "primary" : "secondary"}>{channel.channelID}</Button>
                            )
                        }
                        {
                            this.state.channelsToNonHighlight.map((channel, index) =>
                                <Button key={index} name={channel.channelID} value={channel.channelID}
                                        onClick={this.onClick} variant="contained"
                                        color={channel.inspected ? "primary" : "secondary"}>{channel.channelID}</Button>
                            )
                        }
                    </div>
                </div>
            );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-13
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 2021-05-24
      • 2014-02-11
      • 1970-01-01
      相关资源
      最近更新 更多