Reputation:
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
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
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
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
Reputation: 24
Maybe have a look at context: https://reactjs.org/docs/context.html It could help with your issue
Upvotes: 0