Miltosh
Miltosh

Reputation: 91

Cannot read property 'value' of null Error in first render

I try get a value of my option/select for use it in states in future, but when I try get element by ID, i got error "Cannot read property 'value' of null"

import React from "react";

function Inputs() {
  const Period = document.getElementById("Period");

  console.log(Period);

  const inputHandler = (inputName) => {
    console.log(inputName.value);
  };

  return (
    <div>
      <label>Period:</label>
      <select id="Period" onChange={() => inputHandler(Period)}>
        <option>Last 12 month</option>
        <option>Last 6 month</option>
        <option>Last month</option>
      </select>
    </div>
  );
}

export default Inputs;

Link to the SandBox

Upvotes: 1

Views: 408

Answers (4)

user1
user1

Reputation: 1135

It's not recommended to use document.getElementById with React this way.

You need to understand that you are using jsx which is a templating engine that reads all the tags that your component is returning and compiles it to JavaScript in order to generate the HTML. So what you are doing is trying to query the element before it's rendered and thats why you get null.

You could use a lifecycle callback like componentDidMount or a hook like useEffect in order to get notified when the HTML was rendered and then use document.getElementById but it's not recommended to access elements like this.

In order to get a reference to the element you can use refs even though it's better to create a handler for the onChange event and get the value from the event target.

Upvotes: 1

Grazielle Carvalho
Grazielle Carvalho

Reputation: 453

Check the solution bellow:

import React from "react";

function RechartsInputs() {
  const Period = document.getElementById("Period");

  console.log(Period);

  const inputHandler = (e) => {
    console.log(e.target.value);
  };

  return (
    <div>
      <label>Period:</label>
      <select id="Period" onChange={e => inputHandler(e)}>
        <option>Last 12 month</option>
        <option>Last 9 month</option>
        <option>Last 6 month</option>
        <option>Last 3 month</option>
        <option>Last month</option>
      </select>
    </div>
  );
}

export default RechartsInputs;

hope it helps ;D

Upvotes: 1

wangdev87
wangdev87

Reputation: 8751

Your logic is wrong. Follow with this. Use useEffect and useState.

import React, { useEffect, useState } from "react";

function RechartsInputs() {
  const [val, setVal] = useState(null);

  useEffect(() => {
    console.log(val);
  }, [val]);

  const inputHandler = (event) => {
    setVal(event.target.value);
  };

  return (
    <div>
      <label>Period:</label>
      <select id="Period" onChange={inputHandler}>
        <option>Last 12 month</option>
        <option>Last 9 month</option>
        <option>Last 6 month</option>
        <option>Last 3 month</option>
        <option>Last month</option>
      </select>
    </div>
  );
}

export default RechartsInputs;

Upvotes: 1

Maheer Ali
Maheer Ali

Reputation: 36564

You are trying to access the input before the render at that time it will be obviously null

Use the event.target to access the input

import React from "react";

function Inputs() {

  const inputHandler = (e) => {
    console.log(e.target.value);
  };

  return (
    <div>
      <label>Period:</label>
      <select id="Period" onChange={(e) => inputHandler(e)}>
        <option>Last 12 month</option>
        <option>Last 6 month</option>
        <option>Last month</option>
      </select>
    </div>
  );
}

export default Inputs;

Upvotes: 0

Related Questions