Remove item from String Array ReactJS - reactjs

I'm working with ReactJS with Typescript and the goal is to have a checkbox component that adds and removes items to a string array according to whether the checkbox is selected or not. My current function only adds to the array, so when I select then unselect a checkbox the item is added twice. Thanks in advance.
Function:
const handleGroupChange = (groupOptions: any) => {
const existSelection = selectedGroups;
existSelection.push(groupOptions.target.value);
setSelectedGroups(existSelection);
}
};
Checkbox:
<FormControlLabel
control={
<Checkbox
color="primary"
onChange={e => handleGroupChange(e)}
value={"MATCHED_MENTORS"}
/>
}

check whether checkbox is checked or not on the onChange event.
const handleGroupChange = (groupOptions: any) => {
const existSelection = selectedGroups;
if (groupOptions.target.checked) {
existSelection.push(groupOptions.target.value);
} else {
var index = existSelection.indexOf(groupOptions.target.value);
if (index !== -1) {
existSelection.splice(index, 1);
}
}
setSelectedGroups(existSelection);
}

You need to check the checkbox boolean property whether it is checked or not. Please follow this example below and here is the Codesandbox
const [selectedGroups, setSelectedGroups] = useState([]);
const handleGroupChange = (groupOptions) => {
let existSelection = selectedGroups;
if (groupOptions.target.checked)
existSelection.push(groupOptions.target.value);
else
existSelection = existSelection.filter(item => item !== groupOptions.target.value)
console.log(selectedGroups);
setSelectedGroups(existSelection);

The thing here is that you are pushing a boolean as item therefore the existSelection array should look something like [true, false, true, false] more or less. That should be something to take a look at if it is the behavior you want.
If I understood corretcly what you want is to practice, maybe you can try this:
const randomStrings = ['gelato', 'frozen_yogurt', 'ice_cream'];
and then when you click on the Checkbox it will trigger onChange wich will be connected to handleGroupChange function and this would look something like:
const handleGroupChange = (isChecked) = {
if(isChecked){
//We create a random number between 0 and 2
const randomIndex = Math.floor(Math.random() * 2);
//We select an element from randomStrings array based on the random
index generated above
const randomStr = this.randomStrings[randomIndex];
//Looks if the randomStr already exist in existSelection
if nothing found it findIndex returns - 1 wich tell us
this item is not in the array so we push it.
const existInArr = this.existSelection.findIndex(randomStr);
if(existInArr === - 1){
existSelection.push(randomStr);
}
//I guess you also wanna feed a useState hook here.
setExistSelection(randomStr);
}
};
This should do the trick.

Related

Filter Checkbox issue in react js

This is my code for the category filter. I used this in all places.
{categapi.map((data, index) => (
<Form.Check
onChange={props.handleSingleCheck }
key={index}
name={data.category_id}
label={data.category_name}
type="checkbox"
id={data.category_name}
/>
))}
It's the function for the handle the checkbox.
const handleSingleCheck = (e) => {
if (e.target.checked == true) {
const { name } = e.target;
isChecked.push(name);
console.log(isChecked);
setIsChecked([...isChecked]);
} else {
let index = isChecked.indexOf(e.target.name);
isChecked.splice(index, 1);
}
catfilter();
};
when selecting two categories it is selected. But when I click the more button it opens the modal but the selected items are disabled in the modal.
When clicking on the checkbox it needs to check both inside the modal and outside the modal. How to do this?
In your handleSingleCheck function you are pushing the values and slicing the state variable isChecked directly. Which is the wrong way to interact with react state. Learn more here (you should treat the state variables as if they were immutable)
Change your handleSingleCheck logic as follows:
const handleSingleCheck = (e) => {
let isCheckedCopy = [...isChecked] // create a local variable
if (e.target.checked == true) {
const { name } = e.target;
isCheckedCopy.push(name) // push the data into local mutable array
} else {
let index = isCheckedCopy.indexOf(e.target.name);
isCheckedCopy.splice(index, 1); // slice the mutable array
}
console.log(isCheckedCopy);
setIsChecked([...isCheckedCopy]); // change isChecked state through setIsChecked(...)
catfilter();
};

How to select single sub item from every item in React Native

i am trying to select only one sub-item from every item like this photo:
what i am trying to do:
push an array with index:color, value:black.
when i choose red, to update array with: index:color, value:red.
and the CHECKBOX should be checked only with the selected sub-item (red or black).
this is my onPress function:
const [optionsSelected,setOptionsSelected] = useState([]);
const checkSelected = (optionid,valueid) =>{
if(optionsSelected && optionsSelected.length>0){
if(optionsSelected[optionid] && optionsSelected[optionid]!=undefined){
optionsSelected[optionid]=valueid;
}
}else{
setOptionsSelected(oldArray => [...oldArray, {[optionid]:valueid}]);
}
}
Why not use a plain object instead of an array?
setOptionsSelected(prev => ({
...prev,
[optionid]: valueid,
});
ok i found the solution:
first, this is the updated code:
const checkSelected = (optionid,valueid) =>{
setOptionsSelected(oldArray => ({...oldArray,[optionid]:valueid}));
}
then, this is my check:
if(optionsSelected[item.option_id] && optionsSelected[item.option_id]==item.value_id){
//checked=true;
}else{
//checked=false;
}
thank you all.

how do we push a checkbox to an array while checkbox is by default checked in react js?

the checkbox by default checked if this checkbox is by default checked then it should be automatically pushed into addtess_type array.
https://react-jkrrcb.stackblitz.io demo
handleInputChangeDom = (event) => {
const target = event.target;
var value = target.value;
const Address_type = this.state.Address_type;
if (event.target.checked) {
Address_type.push(event.target.value);
} else {
let index = Address_type.indexOf(event.target.value);
Address_type.splice(index, 1);
}
this.setState({
Address_type: Address_type,
});
};
I think you are trying to maintain a state of all the checked items.
One advice would be to use Set instead of an array. It will make life so much more easier for you.
const handleInputChangeDom = (event) => {
const newSet = new Set(this.state.Address_type); // create a clone, don't update current state
if(event.target.checked) {
newSet.add(event.target.value);
} else {
newSet.delete(event.target.value);
}
this.setState({ Address_type: newSet });
}
One suggestion - please try to use camelCase with React, that is suggested.

ReactJs UseState : insert element into array not updating

I am trying to use React Hooks but somehow my state is not updating. When I click on the checkbox (see in the example), I want the index of the latter to be added to the array selectedItems, and vice versa
My function looks like this:
const [selectedItems, setSelectedItems] = useState([]);
const handleSelectMultiple = index => {
if (selectedItems.includes(index)) {
setSelectedItems(selectedItems.filter(id => id !== index));
} else {
setSelectedItems(selectedItems => [...selectedItems, index]);
}
console.log("selectedItems", selectedItems, "index", index);
};
You can find the console.log result
here
An empty array in the result, can someone explain to me where I missed something ?
Because useState is asynchronous - you wont see an immediate update after calling it.
Try adding a useEffect which uses a dependency array to check when values have been updated.
useEffect(() => {
console.log(selectedItems);
}, [selectedItems])
Actually there isn't a problem with your code. It's just that when you log selectedItems the state isn't updated yet.
If you need selectedItems exactly after you update the state in your function you can do as follow:
const handleSelectMultiple = index => {
let newSelectedItems;
if (selectedItems.includes(index)) {
newSelectedItems = selectedItems.filter(id => id !== index);
} else {
newSelectedItems = [...selectedItems, index];
}
setSelectedItems(newSelectedItems);
console.log("selectedItems", newSelectedItems, "index", index);
};

How to catch remove event in react-select when removing item from selected?

first of all, thanks for awesome work. It makes a lot easier for me. Then here i want to catch remove event, how can I do that? I read the documentation and could not find remove event
I don't think they have an event for that. They just have the onChange.
So, to detect if some option was removed, you would have to compare the current state with the new values the onChange emitted.
Example:
handleOnChange(value) {
let difference = this.state.selected.filter(x => !value.includes(x)); // calculates diff
console.log('Removed: ', difference); // prints array of removed
this.setState({ selected: value });
}
render() {
return (
<div>
<Select
multi={this.state.multi}
options={this.state.options}
onChange={this.handleOnChange.bind(this)}
value={this.state.selected}
showNewOptionAtTop={false}
/>
</div>
);
}
Demo: https://codesandbox.io/s/7ymwokxoyq
React Select exposes a variety of eventListeners to you via props. The onchange function prop now has the following signature. (value: ValueType, action: ActionType).
Accordingly, you can get these events:
select-option, deselect-option, remove-value, pop-value, set-value, clear, create-option, through which you can handle creation and deletion.
Please refer to documentation
They don't have any event for that. I was facing the same problem but in my case, I was needing both the added and removed item. In case someone wants the both values
import 'difference' from 'lodash/difference'
this.currentTags = []
handleChange = (options) => {
const optionsValue = options.map(({ value }) => value)
if (this.currentTags.length < options.length) {
const addedElement = difference(optionsValue, this.currentTags)[0]
this.currentTags.push(addedElement)
console.log("addedElement",addedElement)
//call custom add event here
}
else {
let removedElement = difference(this.currentTags, optionsValue)[0]
console.log("removedElement", removedElement)
// call custom removed event here
let index = this.currentTags.indexOf(removedElement)
if (index !== -1) {
this.currentTags.splice(index, 1)
}
}
}
This code of snippet is working for me to know if any item is removed
I am calling handle change function on onChange event in reat-select
const [selectedGroups, setSelectedGroups] = useState([]);
const handleChange = (value) => {
const diifer = value.length <= selectedGroups.length;
if(diifer){
// item is removed
}
var arr = value.map((object) => object.value);
setSelectedGroups(arr);
};

Resources