在Javascript中使用load事件的竞争条件

时间:2017-10-21 08:36:24

标签: javascript jquery reactjs

所以这或多或少是代码

对不起语法,我是通过手机输入的

export default class Main extends React.Component {

  componentDidMount() {
    axios.get('/user?ID=12345')
  .then(function (response) {
    if (response){
    document.addEventListener('load', () => {/* remove spinner using jquery */});
} else { /* redirect to somewhere else */}
  })
  }

  render() {
    return (
      <SomeComponent />
    );
  }
}

我在反应中使用了addEventListener,因为我找不到任何其他方法来将加载微调器的移除绑定到加载事件。

问题是这里存在争用,对于慢速网络站或快速CPU站点,加载事件可能在请求解决之前很久就会启动,这会导致加载微调器保留。

是否有办法检查加载事件是否已经被加载?

如果我可以这样做,我可以在添加事件监听器后检查它,如果它已经启动,我将手动删除微调器。

1 个答案:

答案 0 :(得分:3)

我不会使用jquery执行此任务(或根本没有反应),因为您可以采用更“反应”的方式来执行此操作。
您可以将数据存储在state中,并在状态发生变化时有条件地在render方法中呈现组件。
顺便说一句,你无法避免第一个render

小例子:

const Loader = () => <div>Loading...</div>

const MyComponent = ({message}) => <div>{message}</div>

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: ''
    };
  }

  componentDidMount(){
    // mimic async operation
    setTimeout(()=>{
      this.setState({message: 'Hi there!'})
    }, 1500);
  }

  render() {
    const {message} = this.state;
    return (
      <div>
        {message ? <MyComponent message={message} /> : <Loader />}
      </div>
    );
  }
}

ReactDOM.render(<App />, 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>

修改
作为评论的后续内容:

  

然后你重新渲染整个组件只是为了改变显示   预载器元素的样式,对吧?

不完全正确我认为您应该阅读有关Reconciliation and The Diffing Algorithm的更多信息并查看this示例:

  

React DOM将元素及其子元素与前一元素进行比较,   并且只应用将DOM带到的DOM更新   期望的状态。