kahjuksEi
kahjuksEi

Reputation: 135

Dynamical render in react by input value

I find the solution to render new fields according to inputed value. How to do it by the right way? I create the function that must return elements when user enter the value to input with id="players". For example, if user enter 5, then function should render 5 inputs in id="playersList".

function PrimaryInputs() {
  const [playersQuantity, setPlayersQuantity] = useState(0);

  function handleChange(event) {
    setPlayersQuantity(event.target.value);
    }

  return (
          <>
           <div class="input_wrapper">
            {playersQuantity}
             <label htmlFor="players">How many players</label>
               <input
                 type="number"
                 name="players"
                 id="players"
                 onChange={handleChange}
               />
            <div id="playersList">
              {playersQuantity.map(() => (
                <div class="playersBlock">
                  <input
                    type="number"
                    placeholder="cups"
                    class="plCup"
                  />
                </div>
              ))}
            </div>
          </>
        );
      }

Upvotes: 1

Views: 22

Answers (2)

dreambold
dreambold

Reputation: 3050

You just need to iterate the number of playersQuantity and add the elements counted. The working code is:

import { useState} from "react";

export default function PrimaryInputs() {
  const [playersQuantity, setPlayersQuantity] = useState(0);

  function handleChange(event) {
    setPlayersQuantity(event.target.value);
  }

  function iterator(quantity) {
    let elems = [];
    for (var i = 0; i < quantity; i++) {
      elems.push(
        <div class="playersBlock" key={i}>
          <input type="number" placeholder="cups" class="plCup" />
        </div>
      );
    }
    return elems;
  }
  return (
    <>
      <div class="input_wrapper">
        <label htmlFor="players">How many players? </label>
        <input
          type="number"
          name="players"
          id="players"
          onChange={handleChange}
        />
        <div id="playersList">{iterator(playersQuantity)}</div>
      </div>
    </>
  );
}

The live demo is here: https://codesandbox.io/s/epic-star-828j8u?file=/src/App.js:0-865

Upvotes: 1

Andy
Andy

Reputation: 63524

map will only work on an array - not an integer. There are ways to prefill an array using fill, and then map over that but it's probably easier to just call a function with the count that returns an array of input elements.

const { useState } = React;

function Example() {

  const [ count, setCount ] = useState(0);

  // Parse the input value
  function handleChange(e) {
    setCount(Number(e.target.value));
  }

  // Simple loop from 0 to count pushing in
  // a new input with each iteration
  function addPlayers() {
    const players = [];
    for (let i = 0; i < count; i++) {
      players.push(<input type="text" key={`player${i}`} />);
    }
    return players;
  }

  return (
    <main>
      <section>
        <input
          type="number"
          min="0"
          onChange={handleChange}
        />
      </section>
      <section>
        {addPlayers(count)}
      </section>
    </main>
  );

}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Upvotes: 1

Related Questions