damefolledechat
damefolledechat

Reputation: 13

How do I push a user input into an array with React?

I am a newbie to React and kinda JS. I've scoured this website/internet for an answer and can't find what I'm looking for. I have an array with some defined names to start. I'd like for the user to be able to input their own suggestions and add them to the array. Below is my code so far. The random name caller works just fine, but the input is what's really throwing me. It keeps saying addNewName and saveInput are defined/assigned a value but never used, and that this.state is undefined. Appreciate any help, thank you!

import "./styles.css";
import React, { useState } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const names = [
    {nameCat: "Gibbis"},
    {nameCat: "Janet"},
    {nameCat: "Big Boy"},
    {nameCat: "Martin"},
    {nameCat: "Raccoon Baby"},
    {nameCat: "Bartholo-MEW"},
  ];

  const [activeCat, setActiveCat] = useState(0);
  
  const randomNames = e => {
    const len = names.length;
    setActiveCat(Math.floor(Math.random() * len));
  };

  function saveInput (e) {
    names(e.target.value);
  }

  const addNewName = (e) => {
    let { nameCat, input } = this.state;
    names.push(input);
    setActiveCat({nameCat: nameCat});
  };

return (
  <div class="container">
   <h1 class="gradient-text">let's name that cat!</h1>
    <h4>your cat's name is: <span class="catName">{names[activeCat].nameCat}</span></h4>
    <button onClick={randomNames}>new name!</button>
    <br/>
    <br/>
    <input 
      type="text"
      onChange={this.addNewName}
      />
    <br/>
    <br/>
      <button onChange={(this.saveInput)}>add new name</button>
    </div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Upvotes: 1

Views: 1138

Answers (1)

Amila Senadheera
Amila Senadheera

Reputation: 13225

There is no this inside React function components. And since names is going to change it should be another state. Try like below:

const names = [
  { nameCat: "Gibbis" },
  { nameCat: "Janet" },
  { nameCat: "Big Boy" },
  { nameCat: "Martin" },
  { nameCat: "Raccoon Baby" },
  { nameCat: "Bartholo-MEW" }
];

function App() {
  const [cats, setCats] = React.useState(names);
  const [activeCat, setActiveCat] = React.useState(0);
  const [newName, setNewName] = React.useState("");

  const randomNames = (e) => {
    const len = cats.length;
    setActiveCat(Math.floor(Math.random() * len));
  };

  function saveInput(e) {
    setNewName(e.target.value);
  }

  const addNewName = () => {
    setCats((prevCats) => [...prevCats, { nameCat: newName }]);
    setNewName("");
  };

  return (
    <div className="container">
      <h1 className="gradient-text">let's name that cat!</h1>
      <h4>
        your cat's name is:{" "}
        <span className="catName">{cats[activeCat].nameCat}</span>
      </h4>
      <button onClick={randomNames}>new name!</button>
      <br />
      <br />
      <input type="text" onChange={saveInput} value={newName} />
      <br />
      <br />
      <button onClick={addNewName}>add new name</button>
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

nit: it should be className in JSX elements instead of class in HTML elements.

Upvotes: 1

Related Questions