【问题标题】:Use click handler to change color of button when there are multiple buttons using the same function当有多个按钮使用相同的功能时,使用单击处理程序更改按钮的颜色
【发布时间】:2021-01-12 01:01:49
【问题描述】:

我有三个按钮使用相同的点击处理程序。 - 我的愿望是只在单击时更改一个按钮的颜色。

如果单击了另一个按钮,我希望之前单击的按钮返回颜色“蓝色”(原始状态)。

示例代码如下:

import React, { useState } from 'react';

export default function App() {
    const [state, setState] = useState({
        name: 'bob',
        color: 'blue',
    });

    const handleColor = (e) => {
        setState((state) => ({
            ...state,
            color: 'red',
        }));
    };


    return (
        <div>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me</button>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me 2</button>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me 3</button>
        </div>
    );
}

【问题讨论】:

  • 为什么不为自定义按钮创建一个react组件,让每个按钮都有自己的状态,而不依赖于父组件的全局状态?

标签: javascript reactjs react-hooks state


【解决方案1】:

你看起来像这样吗

const lists = [
  { id: 1, title: "Click 1" },
  { id: 2, title: "Click 2" },
  { id: 3, title: "Click 3" }
];
export default function App() {
  const [selected, setSelected] = useState(0);
  const [state, setState] = useState({
    name: "bob",
    color: "blue"
  });

  const handleColor = (row) => {
    setSelected(row.id);
  };

  return (
    <div>
      {lists.map((list) => (
        <button
          key={list.id}
          onClick={() => handleColor(list)}
          style={{ backgroundColor: list.id === selected ? "red" : "" }}
        >
          {list.title}
        </button>
      ))}
    </div>
  );
}

Live working demo

【讨论】:

  • 嗨 Vahid,这个答案适用于我的情况。 - 你能帮我理解你为什么在handleColor函数中将(行)作为道具传递吗? row 如何引用列表数组? - 另外,我注意到当我将 'title' 更改为 'name' 或任何其他道具时,该功能无法按预期工作。 - 我很乐意将此标记为正确答案,但只需要理解这一点。
  • row 传递给handleColor 允许组件记住哪个id 是活动的(通过setSelected(row.id)),以便在随后的渲染中可以将它与每个列表项的id (list.id === selected) 进行比较确定是否应将其呈现为红色。
  • #rayhatfield 感谢您的解释。 @博士。天马你可以查看#ray hatfield 评论。正如您询问的标题/名称,最好通过 id 处理,因为文本可以复制而不是 id。
  • 谢谢,这是有道理的,我会标记为正确的。如果您有时间,请查看我的沙箱,因为它模仿了我的本地环境。真的需要知道我在做什么是不好的做法(我将所有内容作为状态传递给子组件)。这是链接codesandbox.io/s/suspicious-lake-r7h17?file=/src/Button.js
  • @Dr.Tenma 代码看起来不错...仅删除 const [selected, setSelected] = useState(0);因为您已经在您的州使用 selected
【解决方案2】:

如果您一次只希望一个按钮处于活动状态,请跟踪哪个按钮处于活动状态而不是它的颜色。

// hypothetical list of buttons. these could be objects with labels, etc.
// but for the purposes of this example they're just empty slots.
const buttons = Array(3);

// the index of the currently active button
const [active, setActive] = useState();

return (
  <div>
    { buttons.map((button, index) => ( // render a button for each item in the array
      <button
        style={active === index ? { backgroundColor: 'red' } : {}}
        onClick={() => setActive(index)}>
          Click Me
      </button>
    )}
  </div>
)

【讨论】:

    【解决方案3】:

    您必须为每个按钮维护单独的状态。 你可以做这样的事情

    import React, { useState } from 'react';
    
    export default function Parent() {
    
        const initialButtonState = {
            color1: 'blue',
            color2: 'blue',
            color3: 'blue',
        } 
    
    
        const [state, setState] = useState({...initialButtonState , name: 'bob'});
    
        const handleColor = (colorName) => {
            setState((state) => ({
                ...state,
                ...initialButtonState ,
                [colorName] : 'red'
            }));
        };
    
    
        return (
            <div>
             <button style={{ backgroundColor: color1 }} onClick={ () => handleColor("color1))}>Click Me</button>
             <button style={{ backgroundColor: color2 }} onClick={() => handleColor("color2")}>Click Me 2</button>
             <button style={{ backgroundColor: color3 }} onClick={() => handleColor("color3")}>Click Me 3</button>
            </div>
        );
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2015-01-26
      • 2023-03-18
      相关资源
      最近更新 更多