简体   繁体   English

直接更新状态时不会触发onClick事件处理程序-ReactJS

[英]onClick event handler not firing when updating state directly - ReactJS

I'm new to ReactJS. 我是ReactJS的新手。 I have the following code, in which I try to update UI by updating state using an onClick event handler. 我有以下代码,在其中我尝试使用onClick事件处理程序通过更新state来更新UI。 However, the onClick is not firing and it's not even showing on the final HTML. 但是, onClick不会触发,甚至不会显示在最终的HTML上。 I can see the button but the button is not bound to the event handler. 我可以看到该按钮,但该按钮未绑定到事件处理程序。 My code is: 我的代码是:

import React from 'react';

class App extends React.Component {
   constructor() {
      super();
      this.state = {
         data: []
      }
      this.setStateHandler = this.setStateHandler.bind(this);
   }
   setStateHandler() {
      var item = "setState...";
      var myArray = this.state.data;
      myArray.push(item)
      this.setState({data: myArray})
   }
   render() {
      return (
         <div>
            <button onClick = {this.setStateHandler}>SET STATE</button>
            <h4>State Array: {this.state.data}</h4>
         </div>
      );
   }
}

export default App;

My final HTML rendered on the browser is: 我在浏览器上呈现的最终HTML是:

<html lang="en"><head>
      <meta charset="UTF-8">
      <title>React App</title>
   <style type="text/css"></style></head>

   <body>
      <div id="app">
        <div>
          <button>SET STATE</button><h4>State Array: </h4>
        </div>
      </div>
 <script src="index.js"></script>
</body>
</html>

What am I doing wrong? 我究竟做错了什么?

EDIT: 编辑:

When I change var myArray = this.state.data; 当我更改var myArray = this.state.data; to var myArray = this.state.data.slice(); var myArray = this.state.data.slice(); it works as intended. 它按预期工作。

You shouldn't see onClick handler in your HTML, that's how React works. 您不应在HTML中看到onClick处理程序,这就是React的工作方式。

Working code: 工作代码:

class App extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         data: []
      }
      this.setStateHandler = this.setStateHandler.bind(this);
   }

   setStateHandler() {
      var item = "setState...";
      this.setState(prevState => ({ data: [...prevState.data, item]}));
   }

   render() {
      return (
         <div>
            <button onClick = {this.setStateHandler}>SET STATE</button>
            <h4>State Array: {this.state.data}</h4>
         </div>
      );
   }
}

export default App

The problem in your example is within setStateHandler definition. 您的示例中的问题在setStateHandler定义内。 You are modifying state directly which is not a correct way to update state . 您正在直接修改状态,这不是更新状态的正确方法

   setStateHandler() {
      var item = "setState...";
      this.setState(prevState => ({ data: [...prevState.data, item]}));
   }

In my example I use function as an argument to setState ( read when to use function as argument ) which will pass me a copy of component state. 在我的示例中,我将函数用作setState的参数(请阅读何时将函数用作参数 ),这将向我传递组件状态的副本。 Then I use destructuring assignment (...prevState) to create new array with a item element. 然后,我使用解构分配(... prevState)创建带有item元素的新数组。 At last I return object to be merged into state. 最后,我返回要合并为状态的对象。

Note that I used destructuring assignment for convenience and brevity. 请注意,为了方便和简洁起见,我使用了结构化分配。 You can accomplish the same by just cloning the array: 您只需克隆数组即可完成相同操作:

   setStateHandler() {
      var item = "setState...";
      this.setState(prevState => {
        const newArray = prevState.data.slice();
        newArray.push(item);
        return { data: newArray };
      });
   }

Beside that you should also pass props to base constructor . 除此之外,您还应该将props传递给基本构造函数 But that wasn't the issue in this case. 但这不是本案的问题。

尝试改用{String(this.state.data)}{this.state.data.toString()}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM