TypeError:无法读取未定义的属性'addEventListener'

时间:2019-09-03 17:12:43

标签: reactjs typeerror addeventlistener

我收到此错误消息:“ TypeError:无法读取未定义的属性'addEventListener'”,我也不知道为什么。我认为这与以下事实有关:变量“ el”首次加载零值,但我不确定,我也不知道如何解决该问题。

编辑: 我在答案的帮助下更新了代码。现在,我收到一条新错误消息“ TypeError:无法设置未定义的属性'value'” https://jsfiddle.net/Van_Gram/4vofz6jh/7/

import React, { Component } from 'react';
import { connect } from 'react-redux'
import { addToCart } from './actions/cartActions'
import StackGrid from "react-stack-grid"
import Tilt from 'react-tilt'


// normally these would be `import` statements bundled by webpack
const { ReactDOM } = window;

 class Home extends Component{

   constructor(props) {
     super(props);
     this.unlockStartHandler = this.unlockStartHandler.bind(this);
     this.unlockEndHandler = this.unlockEndHandler.bind(this);
     this.animateHandler = this.animateHandler.bind(this);
     this.successHandler = this.successHandler.bind(this);
     this.maxValue = 150;
     this.speed = 12;
     this.currValue = 0;
     this.rafID = null;
   }

   /*componentDidMount() {
     // bind events
    this.inputRange.addEventListener('mousedown', this.unlockStartHandler, false);
    this.inputRange.addEventListener('mousestart', this.unlockStartHandler, false);
    this.inputRange.addEventListener('mouseup', this.unlockEndHandler, false);
    this.inputRange.addEventListener('touchend', this.unlockEndHandler, false);
   }*/

   // listen for unlock
   unlockStartHandler(e) {
     // clear raf if trying again
     window.cancelAnimationFrame(this.rafID);
     // set to desired value
     this.currValue = +e.target.value;
   }

   unlockEndHandler(e) {
       // store current value
       this.currValue = +e.target.value;
       // determine if we have reached success or not
       if(this.currValue >= this.maxValue) {
           this.successHandler();
           this.sendData();
       }
       else {
           this.rafID = window.requestAnimationFrame(this.animateHandler);
       }
     }

     // handle range animation
   animateHandler() {
     // update input range
     this.inputRange.value = this.currValue;
     // determine if we need to continue
     if(this.currValue > -1) {
       window.requestAnimationFrame(this.animateHandler);
     }
     // decrement value
     this.currValue = this.currValue - this.speed;
   }

   // handle successful unlock
   successHandler = (prevState) => {
     // alert('unlocked');
     // reset input range
     this.inputRange.value = 0;
   };

   sendData = () => {
     this.props.parentCallback(null);
   }

   callbackFunction = (childData) => {
     /*this.setState((prevState) => ({
       counter: prevState.counter + 1,
     }));*/
   }

    handleClick = (id)=>{
        this.props.addToCart(id);
    }



    render(){
        let itemList = this.props.items.map(item=>{
            return(
              <Tilt className="Tilt" options={{ max : 10 }, { perspective : 3000 }, {scale : 0.97}} >
                <div className="card" key={item.id}>
                  <div className="card-image">
                    <img src={item.img} alt={item.title}/>
                  </div>

                  <div className="card-content">
                    <h2 className="card-title">{item.title}</h2>
                    <p>{item.desc}</p>
                    <div className="slider">
                      <h3>Swipe um zu bestellen</h3>
                      <input
                        type="range"
                        defaultValue={0}
                        min={0}
                        max={150}
                        className="pullee"
                        /*ref={(el) => { this.inputRange = el; }}*/
                      />
                    </div>
                    <span to="/" className="btn-floating halfway-fab waves-effect waves-light red" onClick={()=>{this.handleClick(item.id)}}><i className="material-icons">add</i></span>
                  </div>
                 </div>
               </Tilt>

            )
        })

        return(
            <StackGrid
              columnWidth="33.3%"
              gutterWidth={20}
              gutterHeight={20}
              duration={500}
              className="stackGrid"
            >
              {itemList}
            </StackGrid>
        )
    }
}
const mapStateToProps = (state)=>{
    return {
      items: state.items
    }
  }
const mapDispatchToProps= (dispatch)=>{

    return{
        addToCart: (id)=>{dispatch(addToCart(id))}
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(Home)

1 个答案:

答案 0 :(得分:2)

这是比赛条件。这是因为refthis.inputRange之前没有足够快地分配componentDidMount,因此当您尝试向undefined添加事件侦听器时,分配input的时间就是prop

您可以尝试添加条件和各种策略,但这不是“反应”的方式。 React方式也是最简单的方法并非偶然。通过将其设置为input元素内的内联ref,将这些事件侦听器更改为React可以为您处理的综合事件。

除非您需要其他用途,否则请取出<input onMouseDown={this.unlockStartHandler} onMouseStart={this.unlockStartHandler} // and so on /> 并内联添加事件侦听器。

on

反应事件侦听器属性名称始终是普通的JS名称,并在其前面附加Actions.refs(并保留camelCase命名)。