javascript - setState(...) : Can only update a mounted or mounting component. 这通常意味着您在未安装的组件上调用了 setState()

标签 javascript reactjs

我正在使用 WebSocket 与我的服务器进行通信,并在我的 handleSubmit() 函数上输入一些值,并在此基础上与服务器进行通信并将我的状态更新为数据从 ws 收到。 所以,第一次,一切都工作正常。

componentWillUnmount 上,我还与 websocket 进行通信并发送一个操作以停止向我发送数据。但是当我再次尝试与 websocket 通信时,我更新了状态并收到以下错误

Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the UserData component.

下面是代码

 class UserData extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      labelMsg: "",
      showUsr: false,
      deviceDetails: [],
      center: {lat: 20.5837, lng: 78.9629},
      zoom: 5,
      devData: {
          mainPower: "",
          relayState: "",
          motion: "",
          ang: 0,
          lat: 20.5837,
          lng: 78.9629,
          spd: 0
      },
    }
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(e){
    e.preventDefault();
    global.gWebSocket.SendRequest({
      data: { a: "getDevLoc" , d: {idx:1} },
      cb: (d)=> {
        this.setState({
         devData: d.obj,
          center: {lat: d.obj.lat, lng:d.obj.lng}
        })
        console.log("---> ", d.obj);
      }
    })
  }

 componentWillUnmount() {
  global.gWebSocket.SendRequest({
    data: { a: "stopDevLoc" , d: {idx:1} },
    cb: (d)=> {
      console.log("--->", d.obj);
    }
  })
}


  render(){
    var byRegNum = <input type="text" className="form-control text-uppercase" id="name" onChange={this.byRegNo}/>;
    var byHandle = <input type="text" className="form-control" id="handle" onChange={(e)=> this.handle = e.target.value}/>;
    var byMobile = <input type="number" className="form-control" id="mobile" onChange={(e)=> this.number = e.target.value}/>;
    var byEmail = <input type="email" className="form-control" id="email" onChange={(e)=> this.email = e.target.value}/>;
    return(
      <div className="col-lg-12">
        <div className="container">
          <form onSubmit={this.handleSubmit} ref="submit">
            {this.Search("By Registration Number",byRegNum)}
            {this.Search("By User Handle",byHandle)}
            {this.Search("By Mobile Number",byMobile)}
            {this.Search("By Email",byEmail)}
            <div className="text-center">
              <input type="submit" className="btn btn-primary" value="Search"/>
              <label>{this.state.labelMsg} </label>
            </div>
          </form>
      )
   }
 }

我不知道我错过了什么或者我做错了什么。请在这件事上给予我帮助。

谢谢:)

最佳答案

基本上,您的回调在卸载之前开始,并在卸载之后完成,因此当它到达 this.setState 时,它已经卸载了。

解决此问题的最简单方法是跟踪组件何时安装/卸载。 React 中以前有一个方法可以为您执行此操作,但是 now it's recommended to handle this yourself .

这里可以在componentDidMountcomponentWillUnmount中自己设置this._isMounted,然后只调用setState设置后:

class UserData extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      labelMsg: "",
      showUsr: false,
      deviceDetails: [],
      center: {lat: 20.5837, lng: 78.9629},
      zoom: 5,
      devData: {
          mainPower: "",
          relayState: "",
          motion: "",
          ang: 0,
          lat: 20.5837,
          lng: 78.9629,
          spd: 0
      },
    }
    this.handleSubmit = this.handleSubmit.bind(this);
    this._isMounted = false;
  }

  handleSubmit(e) {
    e.preventDefault();
    global.gWebSocket.SendRequest({
      data: { a: "getDevLoc" , d: {idx:1} },
      cb: (d) => {
        if (this._isMounted) {
          this.setState({
            devData: d.obj,
            center: {lat: d.obj.lat, lng:d.obj.lng}
          });
          console.log("---> ", d.obj);
        }
      }
    });
  }

  componentDidMount() {
    this._isMounted = true;
  }

  componentWillUnmount() {
    this._isMounted = false;
    global.gWebSocket.SendRequest({
      data: { a: "stopDevLoc" , d: {idx:1} },
      cb: (d) => {
        console.log("--->", d.obj);
      }
    });
  }

还有一些其他方法可以解决此问题,但它们需要更多的重构。

关于javascript - setState(...) : Can only update a mounted or mounting component. 这通常意味着您在未安装的组件上调用了 setState(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44858466/

相关文章:

javascript - 有谁知道为什么在我的 Windows 8 应用程序中尝试读取文件时使用 'fileEntry.file' 总是失败?

javascript - React JS - 传递子组件的函数

javascript - 动态类更改间歇性工作

javascript - 如何在运行时在 meteor 中编译新模板?

node.js - 如何在 React/NodeJS 身份验证流程中使用 httpOnly cookie 获取用户数据

javascript - 将自定义数据属性注入(inject) REACT `props.children`

javascript - 使用 React 的 useState 处理错误

javascript - ionic 条形码扫描器时间戳集成

reactjs - 如何使用 Tailwind CSS 更改日历图标的颜色?

javascript - 将 createClass 更改为 Component