反应-点击事件立即触发所有同级

时间:2018-11-16 19:10:37

标签: javascript reactjs

我如何让每个<li />收到一个onClick事件,以一次仅一次一个触发

我的目的是根据单击事件更改颜色并显示/隐藏内容。它可以工作,但是在点击给定<li/>的所有所有兄弟姐妹时,它们也会同时被解雇。

我该如何预防?

here's sandbox code

function App() {
  return (
    <div className="App">
      <Market />
    </div>
  );
}

class Market extends Component {
  constructor() {
    super();
    this.state = {
      isColor: false,
      isShow: false,
      fruits: ["Apple", "Banana", "Peach"]
    };
  }

  handleToggle = () => {
    this.setState(currentState => ({
      isColor: !currentState.isColor,
      isShow: !currentState.isShow
    }));
  };

  render() {
    const fruits = this.state.fruits.map((item, i) => (
      <li
        key={i}
        className={this.state.isColor ? "blue" : "red"}
        onClick={this.handleToggle}
      >
        {item}
        <span className={this.state.isShow ? "show" : "hide"}>Show Text</span>
      </li>
    ));
    return <ul>{fruits}</ul>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

3 个答案:

答案 0 :(得分:5)

您的<li>并没有全部触发。 您所有的元素都在检查状态,以查看color和visible是否为true。 因此,对于三种要素,您只有一种状态,当一项为真时,它们全部为真。

您要么想使每个水果都处于状态状态,要么更好,为每个状态各不相同的列表项创建一个新组件,然后通过道具传递水果名称。

我已经分叉了您的沙箱,并快速创建了一个example外观。这是一个核心的反应概念,将事物分解成可重用的模块,并让组件在可能的情况下管理自己的状态。从长远来看,现在真正将这个想法付诸实践将对您真正有益,所以我希望这会有所帮助。

答案 1 :(得分:3)

所有点击处理程序不会同时触发,但是您保留一个变量来指示是否全部显示。

相反,您可以将对象保持在状态,在其中保持键值对指示是否显示项目。

示例

class Market extends React.Component {
  state = {
    fruits: ["Apple", "Banana", "Peach"],
    isShown: {}
  };

  handleToggle = item => {
    this.setState(currentState => ({
      isShown: { ...currentState.isShown, [item]: !currentState.isShown[item] }
    }));
  };

  render() {
    return (
      <ul>
        {this.state.fruits.map((item, i) => (
          <li
            key={i}
            style={{
              backgroundColor: this.state.isShown[item] ? "blue" : "red"
            }}
            onClick={() => this.handleToggle(item)}
          >
            {item}
            <span
              style={{
                display: this.state.isShown[item] ? "inline-block" : "none"
              }}
            >
              Show Text
            </span>
          </li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(<Market />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

答案 2 :(得分:1)

这是@SpeedOfRound建议的方法的有效沙箱。为每个li创建一个独立的组件,以便该元素具有自己的状态。与@Tholle的回答相比,我不知道这种方法是否有效。

沙盒[https://codesandbox.io/s/1vyonx0zrl]