I have a collection of data. I've mapped the data and passed it to my child component. I pass the items from my child component to my custom checklist. When I click each item, I can select and deselect it.
I'd like to select all of the items. I did this by adding one button to my parent component. When the user clicks the "Select All" button. It will take all data identifiers and pass them to the local state. It works, but I don't think it's the best solution. Because In my checkbox, I'm passing the boolean value of the selected item to the checkbox's component local state. When I press the all-in-one button. This local state does not change. It displays a false value by default.
I reproduce code in code-sandbox
This is my parent component
import "./styles.css";
import Multipicking from "./MultiPicking";
import React, { useState } from "react";
export default function App() {
const Data = [
{
id: "FF",
level: 2,
name: "rice"
},
{
id: "AA",
level: 2,
name: "juice"
},
{
id: "GAA",
level: 2,
name: "ball"
},
{
id: "FF3AA",
level: 2,
name: "TV"
},
{
id: "FH",
level: 2,
name: "Pencil"
},
{
id: "FHAA",
level: 2,
name: "Tea"
}
];
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const checkAllItems = (): void => {
const test = Data.map((item) => item.id);
setSelectedIds(test);
};
return (
<div className="App">
<button onClick={checkAllItems}>select all</button>
{Data.map((item, index) => (
<Multipicking
selectedIds={selectedIds}
setSelectedIds={setSelectedIds}
key={index}
item={item}
index={index}
/>
))}
</div>
);
}
This is my child component
import React from "react";
import MultiPickingItemsCheckBox from "./MultiPickingItemsCheckBox";
interface Props {
item?: any;
index?: number;
selectedIds?: string[];
setSelectedIds?: (selectedIds: string[]) => void;
}
const MultiPickingItems: React.FC<Props> = ({
item,
selectedIds,
setSelectedIds
}) => {
return (
<>
<MultiPickingItemsCheckBox
name={`${item.level} ${item.name}`}
id={item.id}
setSelectedIds={setSelectedIds}
selectedIds={selectedIds}
level={item.level}
selected={selectedIds.includes(item.id)} // selected
/>
</>
);
};
export default MultiPickingItems;
This is the checkbox component
import React, { useState } from "react";
import styled from "styled-components";
const Label = styled.label<{
selected: boolean;
}>`
display: flex;
background: ${({ selected }): string => (selected ? "lightblue" : "gray")};
justify-content: space-between;
align-items: center;
width: auto;
height: 50px;
margin-bottom: 16px;
border-radius: 2px;
font-size: 16px;
padding: 4px;
border-left-width: 3px;
border-left-style: solid;
`;
const Left = styled.span`
display: flex;
flex-direction: column;
flex: 1;
text-align: left;
padding: 4px;
`;
const Name = styled.span`
font-size: 18px;
padding-bottom: 6px;
`;
const Check = styled.input.attrs({
type: "checkbox"
})`
position: absolute;
z-index: -1;
width: 0;
height: 0;
opacity: 0;
`;
const SVG = styled.svg.attrs({
width: 30,
height: 30,
viewBox: "0 0 100 100"
})``;
const Circle = styled.circle.attrs({
r: 35,
cx: 50,
cy: 45,
strokeWidth: 5,
transform: "rotate(-90, 50, 50)"
})<{ checked: boolean }>`
fill: transparent;
stroke-dasharray: 282.743;
stroke-dashoffset: ${({ checked }): number => (checked ? 0 : 282.743)};
stroke: "red";
transition: all 0.3s linear;
`;
const Mark = styled.path.attrs({
d: "M25 50l15 18 24 -40",
fill: "none",
strokeWidth: 8
})<{ checked: boolean }>`
transition: all 0.3s linear;
stroke-dashoffset: ${({ checked }): number => (checked ? 0 : 100)};
stroke-dasharray: 100;
stroke: "red";
`;
interface Props {
name?: string;
selectedIds?: string[];
setSelectedIds?: (selectedItemsId: string[]) => void;
disabled?: boolean;
id?: string;
isDragging?: boolean;
level?: number;
selected?: boolean;
}
const MultiPickingItemsCheckBox: React.FC<Props> = ({
name,
selectedIds,
setSelectedIds,
id,
disabled,
level,
selected
}) => {
const [checked, setChecked] = useState(selected);
const handleChange = (): void => {
setChecked(!checked);
if (checked) {
setSelectedIds(selectedIds.filter((selectedId) => selectedId !== id));
} else {
setSelectedIds([...selectedIds, id]);
}
};
console.log({ checked });
return (
<Label level={level} disabled={disabled} selected={selected}>
<Left>
<Name>{name}</Name>
</Left>
<Check
id={`field-${id}`}
name={name}
checked={checked}
onChange={handleChange}
disabled={disabled}
/>
<SVG>
<Circle checked={checked} />
<Mark checked={checked} />
</SVG>
</Label>
);
};
export default MultiPickingItemsCheckBox;
Aucun commentaire:
Enregistrer un commentaire