将事件侦听器添加到我的页面会导致问题

时间:2020-02-24 22:21:36

标签: javascript html node.js reactjs

在运行yarn start时,由于某种原因,我正在使用react制作一个nodejs应用,但出现此错误“ TypeError:btn_bmi.addEventListener不是一个函数”。任何人都有任何想法,为什么要像过去那样对它起作用,所以我不确定是什么导致了该错误?

import React from 'react';


var btn_bmi = document.getElementsByClassName('bmi_button');
     btn_bmi.addEventListener('click', calculate_bmi());

    function calculate_bmi() {
        let Weight = document.getElementsByClassName('bmi_weight').value;
        let Height = document.getElementsByClassName('bmi_height').value;
        let Age = document.getElementsByClassName('bmi_age').value;
        let Test = document.getElementsByClassName('test_print');
        let bmi_calc = Weight / Height / Height * 10000;
        let bmr_calc = 88.2 + (13.362 + Weight) + (4.799 + Height) - (5.677 + Age);

        //if nothing entered show error
        if (Weight, Height, Age == 0){
            alert("Please enter your Height, Weight and Age so we can achieve your goals!")
            }
            else{
            //
            Test.innerHTML = document.write= bmi_calc + bmr_calc;
            }

    }

function setup_page () {
    return (
    <div className='setup_main'>
     <input className= 'bmi_weight' type='number' placeholder='Weight in kg:'></input>
     <input className= 'bmi_height' type='number' placeholder='Height in cm:'></input>
     <input className= 'bmi_age' type='number' placeholder='Age:'></input>
     <button className='bmi_button'>calculate</button>
     <p className='test_print'></p>
     </div>
    );
    }

export default setup_page;

3 个答案:

答案 0 :(得分:4)

document.getElementsByClassName(...)返回一个HTMLCollection,而不是单个HTML元素。那是因为您可以有多个具有相同类名的元素。

如果您想只返回一个,请替换为:

var btn_bmi = document.getElementsByClassName('bmi_button')[0];

或者,更清洁的IMO:

const btn_bmi = document.querySelector('.bmi_button');

但是,实际上,您要做的最好的事情是将事件侦听器放在JSX中。这样,当React输出DOM并重新渲染时,事件附加/分离将为您处理:

<button className='bmi_button' onClick={calculate_bmi}>calculate</button>

答案 1 :(得分:0)

React创建虚拟DOM,document.querySelector和其他类似功能无法访问。如果您希望访问由react创建的内容,则必须使用this (如果您使用的是类组件),或钩挂useRef()(如果使用的是功能组件) (名称可以是其他名称,但我的意思是:const MyComponent = props => ( <some-element />))。为了您的目的,您应该创建一个将其值保持在状态(this.stateuseState()挂钩)中的表单
编辑
下面的答案也很正确,但是如果您使用React渲染html,则document.getElementsByClassname的结果将返回空集合

答案 2 :(得分:0)

if (Weight, Height, Age == 0){也可能没有按照您的想法做。