2017-04-22 27 views
0

我基本上是尝试使用事件侦听器并为'message'事件添加一个事件,当该应用程序是某个移动应用程序中的webview时,该事件获取外部事件。ReactJS来自EventListener的事件不要更新视图

问题是当事件进来时,反应组件不会更新。我可以确定该事件确实进入了我的事件监听器函数,但是,即使我做了setState,反应组件也不会更新。

这里是我的代码:

import React, { Component } from 'react'; 
    import logo from './logo.svg'; 
    import './App.css'; 

    var showIfEventHappenedAndReactUpdated = false; 

    class App extends Component { 

     componentDidMount() { 

      //event listener to get events from external views 
      //when this app is used as a webview for example 
      document.addEventListener('message', function(e){ 

       //I can see the event coming through here 
       //However, the react component itself doesn't update 
       showIfEventHappenedAndReactUpdated = true; 

       //I have even tried putting a this.setState({}) here but it doesn't work...as it doesn't update the react-component 

      }) 
     } 

     render() { 

     if(showIfEventHappenedAndReactUpdated){ 
      return (
       <div className="App"> 
       <p>Event Occured and React Updated</p> 
       </div> 
      ); 
     }else{ 
      return (
       <div className="App"> 
       <p>Event DID NOT OCCUR YET</p> 
       </div> 
      ); 
     } 

     } 
    } 

    export default App; 

,但如果我得到的 'P' 标签内部这样

import React, { Component } from 'react'; 
    import logo from './logo.svg'; 
    import './App.css'; 



    class App extends Component { 

     componentDidMount() { 

      //event listener to get events from external views 
      //when this app is used as a webview for example 
      document.addEventListener('message', function(e){ 

       document.getElementsByTagName('p')[0].innerHTML = "EVENT OCCURED" 
      }) 
     } 

     render() { 
      return (
       <div className="App"> 
       <p>Event HAS NOT Occured</p> 
       </div> 
      ); 
     } 

     } 
    } 

    export default App; 

然后它工作。唯一的线变化是

document.getElementsByTagName('p')[0].innerHTML = "EVENT OCCURED" 

不过,我需要实际更新视图作出反应,而不是改变原始的DOM元素中的文字。

为了实现这个目标我需要做些什么?

+0

我还没有开始ReactJS但我已阅读文档,并发现当状态属性更改时,React将呈现DOM(React Component),因此如果您使用的事件侦听器比组件不会更改。你必须更新任何状态值并且工作正常。 –

+0

@YogeshPatel我试着做this.setState({})但它仍然没有'更新组件 –

回答

0

如果您尝试在事件处理程序中设置状态,您不会收到错误吗? addEventListener会将你的this设置为处理程序绑定的目标,这应该是你的案例中的文档。除非你的文档有某种setState方法,否则应该抛出一个错误。

只需使用箭头函数就可以修复它,或者当您将它添加为事件侦听器时,将您的处理程序显式绑定到当前的处理程序。

如果你没有收到错误并且绑定你的函数没有帮助,试着在添加事件监听器之前以及在事件监听器中检查this.setState并检查它们是否是相同的函数。或者,尝试向你的setState添加一个回调来检查它是否被调用。

+0

尝试使用箭头函数和绑定回调....仍然不更新 - Zunair Syed刚才编辑 –

+0

我会尝试看看他们是否使用console.log相同的功能,因为你提到 –

0

你的回调函数没有绑定到反应组件,因此setState是未定义的。 console.log(这个)在你的回调中看到。

要修复它,要么绑定回调的this(.bind(this)),要么使用箭头函数,如果你有babel和没有设置。

+0

尝试使用箭头函数和绑定回调....仍然不更新 –

0

你有2个问题在你的代码,因为它是在写这篇的时候:

  1. 你在事件监听器函数未绑定到你的反应元。正如其他人所说,使用箭头语法将解决此问题。

  2. 您正在更新非状态变量。 React只会在3个条件下渲染你的组件:它通过了新的道具,你调用setState()(有一个新的状态,并且你必须在你的构造函数中返回一个状态),或者你调用这个.forceUpdate()。更改全局变量不会导致渲染。

+0

嘿,所以箭头函数并没有解决它。另外我以前试过setState((我的状态在这里)),现在只是尝试this.forceUpdate()。没有工作:( –

+0

您的应用程序的工作版本:http://codepen.io/nivekmai/pen/qmNpWo – nivekmai

-1

首先,showIfEventHappenedAndReactUpdated不是组件状态的一部分,因此当您更新组件时,组件不知道它需要更新。在您的组件添加一个构造方法是这样的:

constructor(props){ 
    super(props); 
    this.state = { showIfEventHappenedAndReactUpdated: false }; 
} 

然后用this.setState({showIfEventHappenedAndReactUpdated : true})更新值。这将使组件再次呈现,并且它将使用新值。其次,回调函数没有绑定到组件的作用域,并在被调用时创建一个新的作用域。无论是在函数调用像这样使用.bind(this)

const callback = function(e){ 
    //do stuff 
} 
document.addEventListener('message', callback.bind(this)); 

或者你可以用一个箭头的功能,它不喜欢这个创建自己的范围:

document.addEventListener('message', (e)=>{ //do stuff };

+0

已经尝试两种,可以证实他们没有区别...反应组件不更新 –

+1

这里是一个工作示例https://codepen.io/iarry/pen/Emybqw –