***//How can I change the select value to true of the checked object?***
const App = () => {
const data = [{id:1, msg:"t", select:false}, {id:2, msg:"t2, select:false}]
const handleChange = (e) => {
if(checked){
data.select === true
}
}
//``To check the particular object I want to set the value true for that object and rendered the false as an unchecked value
return(
{data.map(d => {
<Checkbox
value={d}
checked={d.select}
onChange-{handleChange}
/>
}
)
}
You just have to pass the id to handleChange like this:
return(
{data.map(d => {
<Checkbox
value={d}
checked={d.select}
onChange-{(e)=>handleChange(e,d.id)}
/>
}
and change handleChange to be something like this
const handleChange = (e,id) => {
const index = data.findIndex(element => element.id === id) // here we get the index of the element
if(checked){
data[index].select = true
}
}
Related
I am using useState for this object 'selected', i want to get the updated value in this function verifyActive
const [selected, setSelected] = useState({ a: '', b: '' })
and i have a function that is active since a button
const setActive = (value) => {
setSelected({ ...selected, b: value })
verifyActive()
}
const verifyActive=()=>{
console.log('selected', selected) // is not updated
}
...
console.log(selected) //here is value is updated
return (
<button
onchange={(value) => { setActive(value) }}
/>
The local const selected is never going to change, but what you can do is save the new state to a variable, and pass it in to verifyActive:
const setActive = (value) => {
const newState = { ...selected, b: value };
setSelected(newState);
verifyActive(newState);
}
const verifyActive = (value) => {
console.log('selected', value);
}
change your setActive to this way
const setActive = (value) => {
setSelected((prevSelected) => { ...prevSelected, b: value })
verifyActive()
}
I am developing an application on React and I needed to add product checkboxes to the form. Everything works correctly except that the last action (marking or removing the checkbox) does not go to the server (the error is not in the server, I tested it separately). Here is the output of the checkboxes:
<Form.Group className="mb-3">
<Form.Label>Товары</Form.Label>
{prodsl.map((emp, index) =>
<div className="mb-3">
<Form.Check
type='checkbox'
value={emp.id}
name='pp'
checked={checkedState[index]}
onChange={() => handleOnChange(index)}
/>
{emp.name}
</div>
)}
</Form.Group>
And here is the handler (checkedState - an array of checkbox states):
const [prods, setProd] = useState([])
const [checkedState, setCheckedState] = useState(
new Array(555).fill(false)
);
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
let arr = []
const updatedProd = checkedState.map((item, index) => {
if (item) {
arr = [...arr, index]
}
}
);
setProd(arr);
};
Submit form handler:
const newOrder = async () => {
const response = await addOrder(prods, client, emp, d1, d2)
stat++;
}
I tried to do a separate check before sending, I tried to call the function before sending it to a random checkbox so that this change would be the last and would not be counted.
Set states in react are async. It means that your values are not updated immediately after your setstate.
In order to fix the issue, you have 2 options.
Use the updatedCheckedState variable to set your prod:
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
let arr = []
const updatedProd = updatedCheckedState.map((item, index) => {
if (item) {
arr = [...arr, index]
}
}
);
setProd(arr);
};
Move your logic into useEffect:
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
};
useEffect(() => {
let arr = []
const updatedProd = checkedState.map((item, index) => {
if (item) {
arr = [...arr, index]
}
});
setProd(arr);
}, [checkedState]);
And as a suggestion, use arr.push(index) instead of arr = [...arr, index];
I want to create a function that will color the hearts when clicked.
I wrote a function that prints out elements for me, but when I click on any heart, it colors them all.
Where could the problem be?
My code:
const \[userInput, setUserInput\] = useState("");
const \[list, setList\] = useState(\[\]);
const \[hearth, setHearth\] = useState(false);
const \[active, setActive\] = useState(-1);
const handleChange = (e) =\> {
e.preventDefault();
setUserInput(e.target.value);
};
const handleSubmit = (e) =\> {
e.preventDefault();
setList(\[userInput, ...list\]);
setUserInput("");
};
const wishList = (e) =\> {
setHearth(!hearth);
};
useEffect(() =\> {}, \[userInput, list\]);
return (
\<div className="favMusic"\>
<h1>FavMusicList</h1>
\<form\>
\<input value={userInput} onChange={handleChange} type="text" /\>
\<button onClick={handleSubmit}\>Submit\</button\>
\</form\>
<ul className="favMusic__list">
{list.map((i, idx) => {
console.log(idx);
return (
<li key={idx}>
{i}{" "}
<div
id={idx}
onClick={() => wishList(idx)}
className={"hearth" + " " + (hearth ? "true" : "false")}>
<AiOutlineHeart
/>
</div>
</li>
);
})}
</ul>
</div>
I have tried all possible ways from setState to others found on the net but I have no idea how to solve it
Here's a working demo.
Assuming your state data is an array of items, each with its own boolean property indicating whether it's been "liked" by the user:
[
{
id: 1,
liked: true,
title: 'ListItem 1',
},
{
id: 2,
liked: false,
title: 'ListItem 2',
},
// ...
]
Then in your click handler, you'd want to loop over each of the objects to find the item with the corresponding id to change just the boolean property for that one item. For example:
const handleClick = (id) => {
const newLikes = items.map((item) => {
// check the current element's id against the
// id passed to the handler
if (item.id === id) {
// if it matches, update the liked property
// and return the modified object
return { ...item, liked: !item.liked };
}
// if it doesn't match, just return the
// original object
return item;
});
// update state with the new data
setItems(newLikes);
};
I have a button in my component that will execute DeleteNote property which i want to remove an array element on onClick event.
DeleteNote = (id) =>
{
const allNotes = [...this.state.notes];
const selectedNoteIndex = allNotes.findIndex(e => e.id == id)
allNotes.splice(selectedNoteIndex, 1)
this.setState({ notes: allNotes })
}
But this method seems to not re-render the component.
Anyway when i try with this method, it re-render perfectly.
MoveToArchive = (id) =>
{
const allNotes = [...this.state.notes];
const selectedNoteIndex = allNotes.findIndex(e => e.id == id)
allNotes[selectedNoteIndex].archived = true;
this.setState({ notes: allNotes })
}
What is lacking in my DeleteNote property in order to delete an element?
Been reading all resources but nothing seems to work.
Render :
Display = () =>
{
return (
<>
<HeaderContainer notesData={this.state.notes} searchMethod={this.SearchNotes} />
<MainContainer notesData={this.state.notes} deleteMethod={this.DeleteNote} archiveMethod={this.MoveToArchive} activeMethod={this.MoveToActive} />
<NewModal />
<DeleteModal deleteAllMethod={this.DeleteAllNotes} />
</>
)
}
render()
{
return (this.Display())
}
try this:
DeleteNote = (id) =>
{
const allNotes = [...this.state.notes];
const selectedNoteIndex = allNotes.findIndex(e => e.id == id)
allNotes.splice(selectedNoteIndex, 1)
this.setState({ notes: [...allNotes] })
}
Can you try this code for deleting
DeleteNote = (id) => {
const newNotes = this.state.notes.filter(e => e.id !== id)
this.setState({ notes: newNotes })
}
I have a ul that displays users with a checkbox input. When searching for a user by surname/first name, the previously selected input checkboxes are removed. How to prevent it?
function App() {
let copyList = useRef();
const [contacts, setContacts] = useState([]);
useEffect(() => {
fetch(api)
.then((res) => res.json())
.then((data) => {
copyList.current = data;
setContacts(copyList.current);
})
.catch((err) => console.log(err));
}, []);
contacts.sort((a, b) => (a.last_name > b.last_name ? 1 : -1));
const searchHandler = (value) => {
const contactsList = [...copyList.current].filter((x) => {
if (value.toLowerCase().includes(x.last_name.toLowerCase())) {
return x.last_name.toLowerCase().includes(value.toLowerCase());
} else if (value.toLowerCase().includes(x.first_name.toLowerCase())) {
return x.first_name.toLowerCase().includes(value.toLowerCase());
} else if (value === "") {
return x;
}
});
setContacts(contactsList);
};
return (
<div className="App">
<Header />
<SearchBar onSearch={(value) => searchHandler(value)} />
<ContactsList contacts={contacts} />
</div>
);
}
Input component is in ContactsList component.
function Input(props) {
const [isChecked, setIsChecked] = useState(false);
const [id] = useState(props.id);
const handleChange = () => {
setIsChecked(!isChecked);
console.log(id);
};
return (
<input
type="checkbox"
className={style.contact_input}
checked={isChecked}
onChange={handleChange}
value={id}
/>
);
}
When you filter the contacts and update the contacts state, the list in ContactList will be re-rendered as it is a new array which means you will have a new set of Input components with the default state. In order to persist the previously selected items you will also have to store the array of selected IDs in state. The Input component should receive the isChecked and onChange values from props so you can pass in a condition where you check if the current ID is in the list of selected IDs which means it is checked and when the user clicks on it, you can just simply update that array by adding the ID if it's not currently in the array or removing from it if it is already present (copying the array first since it's a state variable).