#javascript #reactjs
#javascript #reactjs
Вопрос:
Я использую reactjs, и у меня есть следующий код моделирования, который упрощен, чтобы лучше понять мой вопрос:
<span onClick={selectHandler}>Select Group 1</span>
<ul>
<li>
<input type="checkbox" id="kw1" name="Group1[]" value="kw1" />
</li>
<li>
<input type="checkbox" id="kw2" name="Group1[]" value="kw2" />
</li>
<li>
<input type="checkbox" id="kw3" name="Group1[]" value="kw3" />
</li>
</ul>
<span onClick={selectHandler}>Select Group 2</span>
<ul>
<li>
<input type="checkbox" id="tr1" name="Group2[]" value="tr1" />
</li>
<li>
<input type="checkbox" id="tr2" name="Group2[]" value="tr2" />
</li>
<li>
<input type="checkbox" id="tr3" name="Group2[]" value="tr3" />
</li>
</ul>
Мой вопрос в том, как мне написать функцию selectHandler, чтобы выбрать все флажки в соответствии с группой. Пример, если пользователь нажмет на группу 1, будут установлены все флажки kw1, kw2 и kw3. И когда пользователь нажимает на группу 2, будут установлены все флажки tr1, tr2 и tr3.
Когда они снова нажмут на группу 1 или группу 2, флажки будут сняты в соответствии с группой соответственно
Комментарии:
1. Вы хотите, чтобы компонент был контролируемым или неконтролируемым?
Ответ №1:
Я бы сказал, что вам нужно будет прикрепить к вашим входным данным checked prop, чтобы вы могли сохранять состояние отдельно для элементов пользовательского интерфейса. Таким образом, вы можете программно установить их состояние в отдельной функции.
Редактировать:
Хорошо, я ввел это в stackblitz, кажется, у меня были некоторые орфографические ошибки: https://stackblitz.com/edit/react-vcqqif?file=src/App.js
const CheckBoxGroup = () => {
const [checked, setChecked] = React.useState({
tr1: false,
tr2: false,
tr3: false,
});
function handleSelectAll() {
setChecked((prevState) => {
/**
* The following converts the boolen values into an array of primitive
* types and checks the length against the selected. If all selected then
* deselect, otherwise select all.
*/
const stateValues = Object.values(prevState);
const fullLength = stateValues.length;
const selectedLength = stateValues.filter(
(selectedState) => selectedState
).length;
if (fullLength === selectedLength) {
return {
tr1: false,
tr2: false,
tr3: false,
};
}
return {
tr1: true,
tr2: true,
tr3: true,
};
});
}
function handleClick(id) {
setChecked((prevState) => ({
...prevState,
[id]: !prevState[id],
}));
}
return (
<>
<button onClick={handleSelectAll}>Select Group 2</button>
<ul>
<li>
<input
type="checkbox"
id="tr1"
name="Group2[]"
value="tr1"
checked={checked.tr1}
onClick={() => handleClick('tr1')}
/>
</li>
<li>
<input
type="checkbox"
id="tr2"
name="Group2[]"
value="tr2"
checked={checked.tr2}
onClick={() => handleClick('tr2')}
/>
</li>
<li>
<input
type="checkbox"
id="tr3"
name="Group2[]"
value="tr3"
checked={checked.tr3}
onClick={() => handleClick('tr3')}
/>
</li>
</ul>
</>
);
};
Комментарии:
1. Просто чтобы добавить к этому, вы должны использовать button вместо элемента span для handleSelectAll было бы лучше по соображениям доступности
2. Привет, Эанна, спасибо, что уделили мне время. Я попытался реализовать это, но когда я устанавливаю один флажок, срабатывают все флажки. Если я поставлю галочку в группе выбора 2, она установит все флажки, но когда я поставлю галочку снова, она не снимет все флажки.
3. @user2601660 Извините за это, я на самом деле не проверял это, если честно, но при проверке сделанного мной редактирования кажется, что я допустил орфографическую ошибку в реквизите, который я использовал в checked . Я добавил пример его использования в stackblitz!
4. Спасибо @Eanna, код в Blitz работает отлично
Ответ №2:
Существует простой пакет, который решает эту проблему сгруппированными флажками.
В вашем случае функция рендеринга будет выглядеть следующим образом:
<CheckboxGroup>
Select All: <AllCheckerCheckbox /><br/>
<Checkbox id="option-0" /><br/>
<Checkbox id="option-1" /><br/>
<Checkbox id="option-2" /><br/>
</CheckboxGroup>
Комментарии:
1. Спасибо Саймону за ваш ответ. Поддерживает ли эта библиотека сгруппированные флажки NextJS? Я попытался установить его, но получил много предупреждений, которые можно увидеть на ibb.co/tpKsTn3
2. @user2601660 Я думаю, что пока он работает, эти предупреждения вообще не имеют смысла :). Если вы считаете, что вам не нужен пакет, попробуйте создать его самостоятельно, как объяснила Эанна Джи в своем ответе.