【问题标题】:Apply active state on clicked button only仅在单击的按钮上应用活动状态
【发布时间】:2019-03-16 01:16:56
【问题描述】:

我有一个按钮可以改变 onClick 的活动状态:

render() {
    return(
      <SomeButton
          onClick={e => this.handleClick(e)}
          id={someId}
          activeStatus={someId === this.state.active ? "active" : "not active"}
      />
    )
}

改变状态的函数:

handleClick(e) {
    e.preventDefault();
    this.setState({ active: e.currentTarget.id });
}

状态:

this.state = {
    active: null
};

接收 activeStatus 道具的按钮:

export default function SomeButton({ activeStatus }) {

    console.log(activeStatus);

    return (
        // button jsx code
    );
}

但是,每次我点击按钮(我在页面上有 3 个该按钮的实例)时,activeStatus console.log 都会显示:

我点击按钮 1:

active
not active
not active

我点击按钮 2:

active
active
not active

我点击按钮 3:

active
active
active

我希望状态会根据单击的活动按钮切换。

我错过了什么?

【问题讨论】:

  • 你确定console.log 行是准确的吗?在控制台输出中添加id
  • 是否可以为整个应用提供3个按钮?找到我认为的问题会更容易。
  • 您能否为初始渲染添加更多代码?
  • // button jsx code 这可能很重要,这个 jsx 的样子。就像你在什么对象上附加了id 和作为props 传递的点击处理程序
  • onClick={e =&gt; this.handleClick(e, someId)}怎么样

标签: javascript reactjs


【解决方案1】:

您可以在数组中设置状态:

this.state = {
    active: [false, false, false] // or just: []
};

handleClick(e) {
    e.preventDefault();
    const activeState = [false, false, false]; // or just: []
    activeState[e.currentTarget.index] = true;
    // button index ^^
    this.setState({ active: activeState });
}

只需将activeStatus 传递给active 状态:

activeStatus={this.state.active}

在你的组件内部,绑定活动状态:

<button className={ activeStatus[0] ? 'active' : 'not-active' }>...</button>
<button className={ activeStatus[1] ? 'active' : 'not-active' }>...</button>
<button className={ activeStatus[2] ? 'active' : 'not-active' }>...</button>

【讨论】:

    【解决方案2】:

    我会使用 e.target.id 而不是 e.currentTarget.id,如果按钮 ID 是静态的,那么您可以将它们放入您的 state 并使用 id 更新 buttonState 对象(几个之一处理方法)。

    工作示例:https://codesandbox.io/s/olmn9k08m5

    一些注意事项:

    • 保持你的状态一致(如果是字符串,保持字符串,如果 它是一个数组,保留任何数组...等等——在下面的示例中 buttonStateobject 并保持为 object)。

    • 另外,您不需要e.preventDefault(),除非您提交 form 或尝试block functionality

    • 始终指定按钮的type(“按钮”或“提交”)

    ShowButton.js

    import React, { Component } from "react";
    import SomeButton from "./SomeButton";
    
    const buttons = ["button1", "button2", "button3"];
    
    export default class App extends Component {
      state = {
        buttonState: {
          button1: "inactive",
          button2: "inactive",
          button3: "inactive"
        }
      };
    
      handleClick = e => {
        const { id } = e.target; // id="button1","button2" or "button3"
        this.setState(prevState => ({
          buttonState: {
            ...prevState.buttonState, // spread out object
            [id]: prevState.buttonState[id] === "active" ? "inactive" : "active" // use the [id] as an object property (ex: "button1") and set the property's value to "active" or "inactive"
          }
        }));
      };
    
      render = () => (
        <div className="container">
          <h1>Controlling Active Buttons</h1>
          {buttons.map(id => (
            <SomeButton
              key={id}
              id={id}
              handleClick={this.handleClick}
              activeStatus={this.state.buttonState[id]}
            />
          ))}
        </div>
      );
    }
    

    SomeButton.js

    import React from "react";
    
    export default ({ activeStatus, handleClick, id }) => (
      <div style={{ marginBottom: 20 }}>
        <button
          type="button"
          style={{ minWidth: 150 }}
          className={`uk-button ${
            activeStatus === "active" ? "uk-button-primary" : null
          }`}
          id={id}
          onClick={handleClick}
        >
          {activeStatus}
        </button>
      </div>
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多