'React value returning undefined

I'm trying to get a specific value back from my input field in my react component but it's returning undefined, I have tried using the useref alone but it's given me the same result( returns undefined, see picture below. I need to get the player names to that I can use their unique ID's as part of an API call that does not list all players, but I do have a JSON file that contains both, so if I can get their names from the input that I have created I can get their Id's and add that to the API to do an API call. can anyone assist me with this? Thanks!

import React from "react";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import "../playercompare.css";
import InputGroup from "react-bootstrap/InputGroup";
import FormControl from "react-bootstrap/FormControl";
import axios from "axios";
import "chart.js/auto";
import { Bar } from "react-chartjs-2";
import { Radar } from "react-chartjs-2";
import getPlayerId from "../Players.js";
import { useState, useEffect, useRef } from "react";
import players from "../Players.js";

const Playercompare = () => {
  // let axiosurl= 'https://statsapi.web.nhl.com/api/v1/people/' +id;
  const playerOneInput = useRef(null);
  const playerTwoInput = useRef(null);
  const [playerOneName, setPlayerOneName] = useState("Choose player name");
  const [playerTwoName, setPlayerTwoName] = useState("Choose player name");

  function playerOneId() {
    let playerOne = setPlayerOneName(playerOneInput.current.textValue);
    console.log(playerOne);
    console.log(players);
    for (let i = 0; i < players.length; i++) {
      if (playerOneInput.current.value == players[i].name) {
      }
    }
  }

  return (
    <Row className="player-compare-row">
      <Col className="col-12 col-lg-4 input-container" id="input">
        <InputGroup className="mb-3 mt-4 input" ref={playerOneInput}>
          <FormControl
            placeholder={playerOneName}
            aria-label="Player Name"
            aria-describedby="basic-addon1"
          />
        </InputGroup>
        <div className="button col-3" onClick={playerOneId}>
          <p>Hello</p>
        </div>
      </Col>

      <Col className="col-12 col-lg-4 offset-lg-4  input-container">
        <InputGroup className="mb-3 mt-4 input" ref={playerTwoInput}>
          <FormControl
            placeholder={playerTwoName}
            aria-label="Player Name"
            aria-describedby="basic-addon1"
          />
        </InputGroup>
        <div className=""></div>
      </Col>
    </Row>
  );
};

export default Playercompare;


Solution 1:[1]

React-Bootstrap's form controls work just like any regular <input> and can be controlled. You don't need to use refs, just states

const [playerOneName, setPlayerOneName] = useState("");

// ...

<InputGroup className="mb-3 mt-4 input">
  <FormControl
    placeholder="Choose player name"
    aria-label="Player Name"
    aria-describedby="basic-addon1"
    value={playerOneName}
    onChange={e => setPlayerOneName(e.target.value)}
  />
</InputGroup>

The <FormControl> is now a controlled component which means its value is driven from state and it uses the change event to update that state.

You can now simply refer to playerOneName, etc in any button event handlers or effect hooks.

const handleClick = () => {
  console.log("You clicked the button");
  console.log("playerOneName:", playerOneName, "playerTwoName:", playerTwoName);
};

useEffect(() => {
  console.log("player name state changed");
  console.log("playerOneName:", playerOneName, "playerTwoName:", playerTwoName);
}, [ playerOneName, playerTwoName ]); // run effect when these change

Here's a super simple demo showing the controlled component

Edit xenodochial-panini-s7oyym

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1