user18056776
user18056776

Reputation:

How can I delete and disable an input element?

This is my App

import React, { useState } from "react";
import Input from "./components/Input";

function App() {
  const [newRow, setNewRow] = useState([]);
  
  
  const addRow = (event) => {
    event.preventDefault();
    setNewRow(
      newRow.concat(<Input key={newRow.length} myKey={newRow.length} />)
    );
  };

  return (
    <div>
      <button onClick={addRow}>Add row</button>
      <ul>
        <Input key={newRow.length} myKey={newRow.length}/>
        {newRow}
      </ul>
    </div>
  );
}

export default App;

And this is my Input component

import "./Input.css";
import React, { useState } from "react";


const Input = (props) => {
    const [updatedList, setUpdatedList] = useState([])
  const deleteRow = (event) => {
    event.preventDefault();
    const key = props.myKey;
    setUpdatedList(updatedList.splice(key, 1));
    console.log(updatedList);
  };
  const disableRow = (event) => {
    event.preventDefault();
  };
  return (
    <li className="item">
      <select>
        <option value="+">+</option>
        <option value="-">-</option>
      </select>
      <input type="text" />
      <button onClick={deleteRow}>Delete</button>
      <button onClick={disableRow}>Disable</button>
    </li>
  );
};

export default Input;

I guess I'm supposed to delete and disable the List HTML element through its key but I'm getting an empty array when I console.log(updatedList). So how can I delete from the original array in the parent component from the child component?

Upvotes: 1

Views: 89

Answers (4)

Tommy Lee
Tommy Lee

Reputation: 1

You should write deleteRow() as props from app.js When you declare deleteRow() inside of individual Input component, that could not manipulate or update the parent values. disableRow() is only usable for individual Input component, while deleteRow() relative with Parent newRow App.js

import React, { useState } from "react";
import Input from "./components/Input";

function App() {
  const [newRow, setNewRow] = useState([]);
  
  
  const addRow = (event) => {
    event.preventDefault();
    setNewRow(
      newRow.concat(<Input key={newRow.length} myKey={newRow.length} deleteRow={deleteRow} />)
    );
  };
  const deleteRow = (key) => {
   console.log(key)
  }

  return (
    <div>
      <button onClick={addRow}>Add row</button>
      <ul>
        <Input key={newRow.length} myKey={newRow.length}/>
        {newRow}
      </ul>
    </div>
  );
}

export default App;

In your component

import "./Input.css";
import React, { useState } from "react";


const Input = (props) => {
    const [updatedList, setUpdatedList] = useState([]) 
    const disableRow = (event) => {
     event.preventDefault();
    };
    return (
     <li className="item">
      <select>
        <option value="+">+</option>
        <option value="-">-</option>
      </select>
      <input type="text" />
      <button onClick={()=>props.deleteRow(props.key)}>Delete</button>
      <button onClick={disableRow}>Disable</button>
     </li>
   );
 };

export default Input;

Upvotes: 0

Mamunur Qureshi
Mamunur Qureshi

Reputation: 46

The const [updatedList, setUpdatedList] = useState([]) is complete redundant. Instead, Lift the state by passing the newRow and the setNewRow directly into to the input component via props and manipulate it from there. Or pass in a function that manipulates it into the input component.

Also, you shouldn't call splice directly on the updatedList because it changes the contents of the list, and splice is an array which is a reference type.

It might be better to use filter(() => boolean) which returns a new array instead of mutation the current on. Or creating a new variable, const updatedListCopy = [...updatedList] and then call splice on that.

Upvotes: 0

Azerpas
Azerpas

Reputation: 304

Add a deleteRow function to your App component.

// App.js
const deleteRow = (key) => {
  setNewRow(newRow.filter(input => input.key != key));
}

Pass it as a prop to your child component and call it onClick.

// Input.js
const deleteRow = (event) => {
    event.preventDefault();
    const key = props.myKey;
    props.deleteRow(key);
  };

updatedList is unnecessary as you already have an array in the parent component.

Upvotes: 1

Mikka
Mikka

Reputation: 24

Maybe have a look at context: https://reactjs.org/docs/context.html It could help with your issue

Upvotes: 0

Related Questions