State Not Getting Set As Required (React, Hooks) - javascript

I am having trouble setting up a state of my component. Kindly check the details as below
Codesandbox link - https://codesandbox.io/s/goofy-glade-z32zp
This is my App Component containing 4 sub components
import React, { useState } from "react";
import "./App.css";
import RadioType from "./components/Radio/RadioQuestion";
import CheckBox from "./components/Checkbox/CheckBox";
import SelectType from "./components/SelectBox/Selectbox";
import Slider from "./components/Slider/slider";
import data from "./components/jsonData/data.json";
const App = (props) => {
const [values, setValues] = useState();
const setAnswerState = (details) => {
let newState = [];
if (values !== null && values !== undefined)
newState = JSON.parse(JSON.stringify(values));
if (newState === null || newState === undefined) {
newState = [];
newState.push(details);
} else {
if (
newState.filter((x) => x.question_id === details.question_id).length ===
0
)
newState.push(details);
else {
let indexOfFilteredObj = newState.indexOf(
newState.filter((x) => x.question_id === details.question_id)[0]
);
newState[indexOfFilteredObj] = details;
}
}
setValues(JSON.parse(JSON.stringify(newState)));
console.log(values)
};
return (
<div className="App">
{JSON.stringify(values)}
{data.map((v, i) => {
return (
<div key={i}>
{v.question_type === "radio" && (
<RadioType details={v} onChange={setAnswerState} />
)}
{v.question_type === "checkbox" && (
<CheckBox details={v} onChange={setAnswerState} />
)}
{v.question_type === "select" && (
<SelectType details={v} onChange={setAnswerState} />
)}
{v.question_type === "slider" && (
<div style={{ marginLeft: "300px" }}>
<Slider details={v} onChangeState={setAnswerState} />
</div>
)}
</div>
);
})}
</div>
);
};
export default App;
Checkbox
import React, { useState } from "react";
const CheckBox = (props) => {
const { details, onChange } = props;
const [checkedValues, setCheckedValues] = useState([]);
const setGlobalState = (value) => {
let answer = value;
let stateObj = {
question_id: details.questionId,
answers: answer,
question_type: "checkbox",
};
onChange(stateObj);
};
return (
<div>
<div>{details.question}</div>
<label>
{details.answers === undefined
? null
: details.answers.map((checkBoxAnswers, index) => {
return (
<div key={index}>
<input
type="checkbox"
name={`checkbox_${details.questionId}`}
value={checkBoxAnswers}
onChange={(e) => {
let currentValues = checkedValues;
if (e.target.checked) currentValues.push(e.target.value);
else {
const index = currentValues.indexOf(e.target.value);
if (index > -1) {
currentValues.splice(index, 1);
}
}
setCheckedValues(currentValues);
setGlobalState(currentValues);
}}
/>
<label key={index}>{checkBoxAnswers}</label>
</div>
);
})}
</label>
<br />
</div>
);
};
export default CheckBox;
Radio
import React from "react";
const RadioType = (props) => {
const { details, onChange } = props;
const setGlobalState = (value) => {
let answer = [value];
let stateObj = {
question_id: details.questionId,
answers: answer,
question_type: "radio",
};
onChange(stateObj);
};
return (
<div>
<div>{details.question}</div>
<label>
{details.answers === undefined
? null
: details.answers.map((radioQuestionAnswers, index) => {
return (
<div key={index}>
<input
type="radio"
name={`radio_${details.questionId}`}
value={radioQuestionAnswers}
onChange={(e) => setGlobalState(e.target.value)}
/>
<label key={index}>{radioQuestionAnswers}</label>
</div>
);
})}
</label>
<br />
</div>
);
};
export default RadioType;
Select
import React from "react";
const SelectType = (props) => {
const { details, onChange } = props;
const setGlobalState = (value) => {
let answer = [value];
let stateObj = {
question_id: details.questionId,
answers: answer,
question_type: "select",
};
onChange(stateObj);
};
return (
<>
<div>{details.question}</div>
<select
name={`checkbox_${details.questionId}`}
onChange={(e) => {
setGlobalState(e.target.value);
}}
>
{details.answers === undefined
? null
: props.details.answers.map((selectAns, index) => {
return (
<option key={index} value={selectAns}>
{selectAns}
</option>
);
})}
</select>
</>
);
};
export default SelectType;
NouiSlider
import React from "react";
import Nouislider from "nouislider-react";
import "nouislider/distribute/nouislider.css";
const Slider = (props) => {
const { details, onChangeState } = props;
const setGlobalState = (value) => {
let answer = [value];
let stateObj = {
question_id: details.questionId,
answers: answer,
question_type: "slider",
};
onChangeState(stateObj);
};
return (
<>
<Nouislider
style={{ color: "red", width: "600px" }}
start={[0]}
pips={{ mode: "count", values: details.division }}
clickablePips
range={{
min: details.range.min,
max: details.range.max,
}}
onChange={(e) => {
let valueOfSlider = parseFloat(e[0]);
setGlobalState(valueOfSlider);
}}
/>
</>
);
};
export default Slider;
Coming to the problem whenever I try to set state from the radio checkbox or select it does set the state and updates correctly via setAnswerState method that is passed as prop to child. Whenever I try to change the slider the setAnswerState gets values as undefined or null, so the complete state that is set by other child components is lost, I am not able to find the reason behind state lost.
Here is the sample data I used for testing
[
{
"question": "When was the Cilivar War?",
"question_type": "radio",
"answers": ["1877-1866", "1877-1872", "1877-1851", "1877-1880"],
"questionId": "099011"
},
{
"question": "World's Largest country by population?",
"answers": ["China", "Canada", "United kingdom", "India"],
"correctAns": "China",
"question_type": "checkbox",
"dependent_question_id": [
{
"question_id": "099011",
"answers_to_match": [
{
"operator": "AND",
"answers": ["1877-1866"]
}
]
}
],
"questionId": "0990758"
},
{
"question": "Where is the Tajmahal?",
"answers": ["Agra", "Mumbai", "Pune", "Punjab"],
"correctAns": "Agra",
"question_type": "select",
"dependent_question_id": [
{
"question_id": "099011",
"answers_to_match": [
{
"operator": "AND",
"answers": ["1877-1866"]
}
]
},
{
"question_id": "099078",
"answers_to_match": [
{
"operator": "AND",
"answers": ["Canada", "United kingdom"]
}
]
}
],
"questionId": "099096"
},
{
"questionId": "0002346",
"question_type": "slider",
"division": 5,
"range":
{
"min": 0,
"max": 100
}
}
]

Just add [] in useState() as shown below:
const [values, setValues] = useState([]);
And then update the setAnswerState method to:
const setAnswerState = (details) => {
// below statement will handle both the cases:
// updating an existing question as well as adding in a new question
setValues((prevValues) => [
...prevValues.filter((x) => x.question_id !== details.question_id),
{ ...details }
]);
};

In your App Component, you need to add [] in useState() as
const [values, setValues] = useState([]);
and inside setAnswerState(), use the newState as the value of setValues().
setValues(newState)
not
setValues(JSON.parse(JSON.stringify(newState)));

Related

How to filter by ingredients on React

Currently I can filter by 1 ingredient, but when i try to select multiple ingredients (checkboxes), My recipes disappear as "ingredient1, ingredient2" is being passed to my searchfield rather than ingredient 1 & ingredient2.
My code for my search/filter is
import React, { useState } from "react";
import DisplayFoodItems from "./DisplayFoodItems";
import { ingredients } from "../data/Ingredients";
function Search({ details }) {
const [searchField, setSearchField] = useState("");
const [checked, setChecked] = useState([]);
const all = [...checked];
const filtered = details.filter((entry) => {
//Search box
if (entry.name.toLowerCase().includes(searchField.toLowerCase()) ||
entry.catagory.toLowerCase().includes(searchField.toLocaleLowerCase())) {
return (
entry.name.toLowerCase().includes(searchField.toLowerCase()) ||
entry.catagory.toLowerCase().includes(searchField.toLocaleLowerCase())
)
}
//Filter checkboxes
for (var i = 0; i < entry.ingredients.length; i++) {
console.log(searchField)
if (entry.ingredients[i].toLowerCase().includes(searchField.toLocaleLowerCase())) {
return (
entry.ingredients[i].toLowerCase().includes(searchField.toLocaleLowerCase())
);
}
}
}
);
const handleToggle = c => () => {
// return the first index or -1
const clickedBox = checked.indexOf(c);
if (clickedBox === -1) {
all.push(c);
console.log(all)
setSearchField(all.toString())
} else {
all.splice(clickedBox, 1);
setSearchField("")
}
console.log(all);
setChecked(all);
};
return (
<>
<div>
<input id="search"
className="form-control"
type="text"
placeholder="Search by recipe name or catagory"
onChange={(e) => setSearchField(e.target.value)}
/>
</div>
<div>
{ingredients.map((ingredient, index) => (
<label key={index} className="form-check-label">
<input
onChange={handleToggle(ingredient.name)}
type="checkbox"
className="mr-2"
/>
{ingredient.name}</label>
))}
<hr></hr>
</div>
<div class="flex">
<DisplayFoodItems foodList={filtered} />
</div>
</>
);
}
export default Search;
Here is a picture of my screen if it helps at all
All checkboxes work individually but for example, if salt and oil when checked together it should return Bacon wrapped chicken and Smashed potatoes, however it returns blank at present.
I have tried looping the all array and sending that to setSearchField, but again, I cannot get it to work.
I have tried looping through the array of checked ingredients and sending that to the setSearchField. Im expecting recipes to appear if they contain an ingredient that has been checked.
If I understand correctly you want something like this?
const foodList = [
{ name: "Food 1", ingredients: ["Salt"] },
{ name: "Food 2", ingredients: ["Oil"] },
{ name: "Food 3", ingredients: ["Milk"] },
{ name: "Food 4", ingredients: ["Salt", "Oil"] },
{ name: "Food 5", ingredients: ["Oil", "Milk"] },
{ name: "Food 6", ingredients: ["Oil", "Salt", "Milk"] },
];
const ingredientList = ["Salt", "Oil", "Milk"]
const Example = () => {
const [ingredients, setIngredients] = useState([]);
const filtered = foodList.filter(food => {
return ingredients.length === 0
|| food.ingredients.length > 0 && ingredients.every(selectedIngredient =>
food.ingredients.some(foodIngredient => foodIngredient.toLowerCase() === selectedIngredient.toLowerCase()));
});
return (
<div>
<h2>Filter</h2>
{
ingredientList.map((ingredient, i) => {
const checked = ingredients.some(selectedIngredient => ingredient.toLowerCase() === selectedIngredient.toLowerCase());
return (
<label key={`ingredient-${i}`}>
<input
type="checkbox"
checked={checked}
onChange={() => {
if (checked) {
setIngredients(ingredients.filter(selectedIngredient => ingredient.toLowerCase()!== selectedIngredient.toLowerCase()))
}
else {
setIngredients([...ingredients, ingredient]);
}
}} />
{ingredient}
</label>
);
})
}
<br />
<br />
<h2>Food list</h2>
<pre>{JSON.stringify(filtered, null, 4)}</pre>
</div>
);
}

When I reload the url useEffect return empty array - React js

When we call filterOnClick function it returns the required "fdata".
Console :
[[Prototype]]: Array(2)
0: {filter: 'countries', values: Array(3), search: '', checkedValue: 'india'}
1: {filter: 'states', values: Array(3), search: '', checkedValue: null}, "fdata"
//Required.
But when we reload the url it returns empty ,
[[Prototype]]: Array(0) [] , "fdata" .
// Universities start here
import React, { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Accordion } from "react-bootstrap";
const filterData = {
data: {
countries: [
{
name: "dubai",
id: 1,
},
{
name: "canada",
id: 2,
},
{
name: "india",
id: 3,
},
],
states: [
{
name: "tamil nadu",
id: 4,
},
{
name: "kerala",
id: 5,
},
{
name: "ttk",
id: 6,
},
],
},
};
const Universities = () => {
const [fdata, setFData] = useState([]);
const [filterTagList, setFilterTagList] = useState([]);
const { countries } = useParams();
let navigate = useNavigate();
useEffect(() => {
Object.entries(filterData?.data).map(([key, values]) => {
let query = {
filter: key,
values: values,
search: "",
checkedValue: null,
};
setFData((fdata) => [...fdata, query]);
});
}, [filterData]);
useEffect(() => {
setCountry();
}, [countries]);
const setCountry = () => {
if (countries) {
if (fdata.length > 0 && countries) {
let ind = fdata.findIndex((e) => e.filter === "countries");
var newStateArray = [...fdata];
newStateArray[ind].checkedValue = countries;
setFData(newStateArray);
}
console.log(fdata, "fdata");
let filterTagIndex = filterTagList.findIndex(
(e) => e.label === "countries"
);
if (filterTagIndex >= 0) {
// exist
const newState = [...filterTagList];
newState[filterTagIndex].value = countries;
setFilterTagList(newState);
} else {
// not exist
setFilterTagList((data) => [
...data,
{ label: "countries", value: countries },
]);
}
}
};
const filterOnClick = (event, label) => {
if (label === "countries") {
navigate(`/universities/study-in-${event.target.value}`);
} else {
navigate(`/universities/study-in-${event.target.value}?state=dubai`);
}
};
return (
<>reload
{fdata?.map((item, idx) => (
<Accordion
className="accordion h-100"
key={item["filter"]}
defaultActiveKey={item["filter"]}
>
<Accordion.Item
eventKey={item["filter"]}
className="accordion-item pb-3"
key={idx}
>
<Accordion.Header
className="accordion-header"
id="panelsStayOpen-headingOne"
>
{item["filter"]}
</Accordion.Header>
<div className="accordion-collapse collapse show">
<Accordion.Body className="p-0">
<div className="options-block">
{Array.isArray(item["values"]) === true && (
<>
{fdata[idx]["search"] !== "" ? (
<>
{item["values"]
.filter(({ name }) =>
name
.toLowerCase()
.includes(fdata[idx]["search"].toLowerCase())
)
.map((val, ind) => (
<div className="form-check mt-3">
<input
className="form-check-input"
type="radio"
value={val["name"]}
id={`filter-${item["filter"]}${ind}`}
checked={item["checkedValue"] === val["name"]}
onClick={(event) =>
filterOnClick(event, item["filter"], idx)
}
/>
<label
className="form-check-label"
htmlFor={`filter-${item["filter"]}${ind}`}
>
{val["name"]}
</label>
</div>
))}
</>
) : (
<>
{item["values"].map((val, ind) => (
<div className="form-check mt-3">
<input
className="form-checkreload-input"
type="radio"
value={val["name"]}
id={`filter-${item["filter"]}${ind}`}
checked={item["checkedValue"] === val["name"]}
onClick={(event) =>
filterOnClick(event, item["filter"], idx)
}
/>
<label
className="form-check-label"
htmlFor={`filter-${item["filter"]}${ind}`}
>
{val["name"]}
</label>
</div>
))}
</>
)}
</>
)}
</div>
</Accordion.Body>
</div>
</Accordion.Item>
</Accordion>
))}
</>
);
};
export default Universities;
// Universities end here
//Home.js start here
import React from "react";
const Home = () => {
return <p>Home page</p>;
};
export default Home;
// Home.js end here
// App.js start here
import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Universities from "./Universities";
import Home from "./Home";
const App = () => {
return (
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/universities" element={<Universities />} />
<Route exact path="/universities/study-in-:countries-cnhp" element={<Universities />} />
</Routes>
</Router>
);
};
export default App;
It's the correct behavior of react state because you can not save your datas in state and expect they be there even by browser refresh so you should save them with api in your database or you can use browser local storage to save your data in browser storage and you can use it by getting them from localStorage

REACT-SELECT defaultValue in CustomDropdown not working

I want the default value of my dropdown to be defaultValue={item.taste} (value from match.json) but it's not working... (go to /menu/Menu1 and Pea Soup)
import Select from "react-select";
export default function CustomDropdown({ style, options, defaultValue }) {
return (
<div style={style}>
<Select options={options} defaultValue={defaultValue} />
</div>
);
}
MenuItemDisplay:
export default function MenuItemDisplay() {
const { menuId, itemId } = useParams();
const { match } = JsonData;
const matchData = match.find((el) => el._id_menu === menuId)?._ids ?? [];
const item = matchData.find((el) => el._id === itemId);
const styles = {
select: {
width: "100%",
maxWidth: 150
}
};
const TASTE = [
{ label: "Good", value: "Good" },
{ label: "Medium", value: "Medium" },
{ label: "Bad", value: "Bad" }
];
...
return (
<>
<div className="TextStyle">
{"Taste "}
<CustomDropdown
style={styles.select}
options={TASTE}
defaultValue={item.taste}
//The default value is not working only if it's
//TASTE[0]
/>
</div>
...
</>
);
}
Here the link for the code
As defaultValue you need to pass one of the objects of the TASTE array. You can do this:
<CustomDropdown
style={styles.select}
options={TASTE}
defaultValue={TASTE.find(t => t.label === item.taste)}
/>

Conditionally disable React Checkbox

I am trying to conditionally disable the checkbox in react, based on the count. Passing the value through props whether it is checked and greater than the number. I am saving the name in the state to further process it to send to in the backend database.
Here is my react code.
class CheckboxComponent extends Component {
constructor(props) {
super(props);
this.state = {
checkedItems: {}
};
}
handleChange = (event, formKey) => {
const {checkedItems} = this.state;
const checkedValues = {...checkedItems};
checkedValues[event.target.name] = event.target.checked;
this.setState((prevState, currState) => {
return {
...prevState,
checkedItems: checkedValues
}
});
};
render = () => {
const {checkedItems} = this.state;
const checkedValues = {...checkedItems};
const checkedCount = Object.values(checkedValues).length;
const checked = Object.values(checkedValues);
const disabled = checkedCount >= 3;
return (
<div>
{checkboxes.map((item, index) => (
<label className={`form__field__input__label`} key={item.key}>
<Input
type={`checkbox`}
name={item.name}
checked={this.state.checkedItems[item.name] || false}
onChange={this.handleChange}
formKey={'subjects'}
disabled={(!checked[index] && checked.length > 3)}
/>
{item.name}
</label>
))}
</div>
)
This is the Array that I am passing to render the values in the checkbox
const checkboxes = [
{
name: "Math and economics",
key: "mathsandeconomics",
label: "Math and economics"
},
{
name: "Science",
key: "Science",
label: "Science"
},
The below code snippet will work fine for you. And you can sent object to the backend having maximum of only 3 properties set to true. Get the full code from codesandbox link https://codesandbox.io/s/emmeiwhite-0i8yh
import React from "react";
const checkboxes = [
{
name: "Math and economics",
key: "mathsandeconomics",
label: "Math and economics",
},
{
name: "Science",
key: "science",
label: "Science",
},
{
name: "history",
key: "history",
label: "history",
},
{
name: "literature",
key: "literature",
label: "literature",
},
];
class CheckboxComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
checkedItems: {},
count: 0,
};
}
handleChange = (event, formKey) => {
const { name, checked } = event.target;
const updatedCheckedItems = { ...this.state.checkedItems, [name]: checked };
this.setState({
checkedItems: updatedCheckedItems,
count: Object.values(updatedCheckedItems).filter((value) => value).length,
});
};
render = () => {
const checkedValues = { ...this.state.checkedItems };
const checkedCount = Object.values(checkedValues).filter((value) => value)
.length;
console.log(this.state.checkedItems);
return (
<div>
{checkboxes.map((item, index) => (
<label className={`form__field__input__label`} key={item.key}>
<input
type={`checkbox`}
name={item.name}
checked={this.state.checkedItems[item.name] || false}
onChange={this.handleChange}
disabled={!checkedValues[item.name] && checkedCount > 2}
/>
{item.name}
</label>
))}
</div>
);
};
}
export default CheckboxComponent;
Your checked.length counts all touched boxes, not checked only. If you uncheck an input, it still will be counted. Count only true, for example Object.values(checkedValues).filter(value => value).length.
Use names instead of indexes: disabled={!checkedValues[item.name] && checkedCount > 3}
You can see full solution here: https://codesandbox.io/s/confident-http-vlm04?file=/src/App.js
event.target.getAttribute('name');
try this to get name attribute, pretty sure event.target.name is 'undefined'
I see one use case is not taken care of. checkedCount should count the number of true values only.
const checkedCount = Object.values(checkedValues).length; // existing
const checkedCount = Object.values(checkedValues).filter(item=>item==true).length //replace with this line
This would solve the problem.
Here is the code and as well as codesandbox link
Codesandbox Link
import React from "react";
export class CheckboxComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
checkedItems: {},
checkedCount: 0
};
}
handleChange = (event, formKey) => {
const { checkedItems } = this.state;
const checkedValues = { ...checkedItems };
checkedValues[event.target.name] = event.target.checked;
this.setState((prevState, currState) => {
return {
...prevState,
checkedItems: checkedValues,
checkedCount: event.target.checked
? prevState.checkedCount + 1
: prevState.checkedCount - 1
};
});
};
render = () => {
const { checkboxes } = this.props;
const { checkedCount } = this.state;
const disabled = checkedCount >= 3;
return (
<div>
<p></p>
{checkboxes.map((item, index) => (
<label className={`form__field__input__label`} key={item.key}>
<input
type={`checkbox`}
name={item.name}
checked={this.state.checkedItems[item.name] || false}
onChange={this.handleChange}
disabled={!this.state.checkedItems[item.name] ? disabled : false}
/>
{item.name}
</label>
))}
</div>
);
};
}

How to toggle between one checkbox and a whole group of checkboxes?

My purpouse here is to create a group of checboxes. "Search everywhere" is default checked, if you check something else "Search everywhere" automatically unchecked, you can check as many different checkboxes as you want, until you check "search everywhere" again, if you do that all other checkboxes will unchecked.
I want to create it in function component with Hooks in React.
View: Image how it looks in browser
Everything is ready, but I stuck a little bit with toggle between one checkbox and group of checkboxes. I've tried useState and useEffect to controll useState callback. Thanks for help.
const ButtonCategory = (props) => {
const [state, setState] = useState({
normalCheckbox: false,
specialCheckbox: true
});
const { id, name, special, products } = props;
const toggleOthers = () => {
if (state.specialCheckbox) {
setState({
...state,
normalCheckbox: false // ofc its bad
});
} else if (state.normalCheckbox) {
setState({
...state,
specialCheckbox: false // ofc its bad
});
}
};
const toggleNormal = () => {
setState({
...state,
normalCheckbox: !state.normalCheckbox
});
};
const toggleSpecial = () => {
setState({
...state,
specialCheckbox: !state.specialCheckbox
});
};
useEffect(() => {
toggleOthers();
}, [state.specialCheckbox, state.normalCheckbox]);
return (
<>
<Label>
<StyledInput
type="checkbox"
id={id}
checked={special ? state.specialCheckbox : state.normalCheckbox}
onChange={special ? () => toggleSpecial() : () => toggleNormal()}
onClick={(e) => {
/* do something */
}}
/>{" "}
<div>
{" "}
{name} {special ? null : `(${products})`}
</div>
</Label>
</>
);
};
I believe you want something like this:
import React, { useState } from "react";
export const Checkboxes = () => {
const [checkedIds, setCheckedIds] = useState(new Set(["everywhere"]));
const handleCheck = ({ id, checked }) => {
if (checked) {
if (id === "everywhere") {
checkedIds.clear();
} else {
checkedIds.delete("everywhere");
}
checkedIds.add(id);
} else {
checkedIds.delete(id);
}
setCheckedIds(new Set(checkedIds));
};
return (
<form>
<label>
<input
id="everywhere"
type="checkbox"
checked={checkedIds.has("everywhere")}
onChange={(e) => handleCheck(e.target)}
/>{" "}
Search everywhere
</label>
<label>
<input
id="option-1"
type="checkbox"
checked={checkedIds.has("option-1")}
onChange={(e) => handleCheck(e.target)}
/>{" "}
Option 1
</label>
<label>
<input
id="option-2"
type="checkbox"
checked={checkedIds.has("option-2")}
onChange={(e) => handleCheck(e.target)}
/>{" "}
Option 2
</label>
</form>
);
};
Test case at codesandbox.io
May be this could be helpful
import React from "react";
import "./style.css";
export const App = () => {
const _checkboxes = [
{
id: "id1",
name: "111",
value: "111",
label: "111",
checked: true
},
{
id: "id2",
name: "222",
value: "222",
label: "222",
checked: false
},
{
id: "id3",
name: "333",
value: "333",
label: "333",
checked: false
}
];
const [checkboxes, setCheckboxes] = React.useState(_checkboxes);
const handleChange = id => e => {
setCheckboxes(checkboxes => {
const firstId = "id1";
const temp = checkboxes.map(c => {
if (firstId === id) {
c.checked = c.id === firstId ? !c.checked : false;
} else {
if (c.id === id) {
c.checked = !c.checked;
} else {
if (c.id === firstId) {
c.checked = false;
}
}
}
return c;
});
return [...temp];
});
};
return (
<div>
{checkboxes.map(checkbox => (
<div key={checkbox.id}>
<input
type="checkbox"
onChange={handleChange(checkbox.id)}
value={checkbox.value}
name={checkbox.name}
id={checkbox.id}
checked={checkbox.checked}
/>
<label htmlFor={checkbox.id}>{checkbox.label}</label>
</div>
))}
</div>
);
};
https://stackblitz.com/edit/react-rtxxfp?file=src%2FApp.js

Categories