Reputation: 491
I'm making a nodejs app using react for some reason when I run yarn start I get this error "TypeError: btn_bmi.addEventListener is not a function". Anyone have any ideas why this would be setting it up like this has worked for me in the past I'm unsure what is causing the error?
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;
Upvotes: 1
Views: 162
Reputation: 136
Also if (Weight, Height, Age == 0){
probably doesn't do what you think it does.
Upvotes: 0
Reputation: 514
React creates virtual DOM which cannot be accessed by document.querySelector and other similar functions. If you wish to access something created by react you must use this
if you are using class component or hook useRef()
if you are using function components(the name can be something else but I mean those: const MyComponent = props => ( <some-element />)
). For your purpose you should create a form which holds its values in a state (either this.state
or useState()
hook)
EDIT
Below answer is quite right too but if you are using React to render your html the result of document.getElementsByClassname will return empty collection
Upvotes: 0
Reputation: 78850
document.getElementsByClassName(...)
returns an HTMLCollection
, not a single HTML element. That's because you can have multiple elements with the same class name.
If you want to assume only one comes back, replace with:
var btn_bmi = document.getElementsByClassName('bmi_button')[0];
Or, IMO the cleaner:
const btn_bmi = document.querySelector('.bmi_button');
But really, the best thing for you to do is to place the event listener in the JSX; that way, the event attachment/detachment is taken care of for you when React outputs the DOM and re-renders:
<button className='bmi_button' onClick={calculate_bmi}>calculate</button>
Upvotes: 4