#reactjs #next.js #react-hook-form #chakra-ui
Вопрос:
Я пытаюсь воспроизвести эту идею родительского и дочернего флажка, представленную в документации ChakraUI.
У меня есть один массив для родительских флажков и один массив для дочерних флажков. Я перебираю родительские флажки и на каждой итерации перебираю соответствующие дочерние флажки и создаю из этого таблицу.
Проблема в том, что всякий раз, когда я добавляю форму React-hook «{…register ()}», флажок перестает работать.
- Когда я нажимаю на него, визуально ничего не происходит (но я вижу, что его значение было изменено с помощью консоли.войдите в систему, когда я нажму «Отправить»).
- Кроме того, если я нажму на родительский флажок, а затем отправлю, функция регистрации не поймает изменение значения в дочерних флажках и консоли.журнал возвращает объект, как если бы дочерние флажки все еще были сняты.
Вот видео того, как это выглядит.
Для «локали» permissaoFilha
= childPermission
и permissaoPai
= parentPermission
. Мои флажки представляют разрешения, которые включены и отключены.
Вот что я передаю:
return (
<>
<Flex as="form" flexDir="column" onSubmit={handleSubmit(submitPermissoes)}>
<Button type="submit" size="sm" colorScheme="green" mr="2">
Save
</Button>
</PageHeader>
<Table>
<Thead>
<Tr>
<Th>
Name
</Th>
</Tr>
</Thead>
<Tbody>
{!loading ? permissoesPai.map((permissaoPai) => {
return (
<React.Fragment key={permissaoPai.id}>
<Tr>
<Td>
<Checkbox
isChecked={allChildrenMarked(permissaoPai.id)}
isIndeterminate={isIndeterminate(permissaoPai.id)}
onChange={(e) => toggleCheckedPai(e, permissaoPai.id)}
defaultChecked={initChecked(permissaoPai.nome)}
>
</Checkbox> {permissaoPai.nome}
</Td>
</Tr>
{permissoesFilhas.map((permissaoFilha) => {
if (permissaoFilha.pai === permissaoPai.id) {
return (
<Tr key={permissaoFilha.id}>
<Td>
<FormControl
>
<Checkbox
name={permissaoFilha.nome}
isChecked={permissaoFilha.checked}
onChange={(event) => toggleCheckedFilha(event, permissaoFilha.id)}
defaultChecked={initChecked(permissaoFilha.nome)}
value={permissaoFilha.checked}
{...register(`${permissaoFilha.nome}`)}
>
</Checkbox> {permissaoFilha.nome}
</FormControl>
</Td>
</Tr>
)
}
})}
</React.Fragment>
)
})
: ''}
</Tbody>
</Table>
</Flex>
</>
)
And here’s the logic for the above:
const { register, handleSubmit, formState } = useForm();
const submitPermissoes = (permissions) => {
console.log(permissions);
}
// separates checkboxes in different arrays for parents and children
const separatePermissions = () => {
setPermissoesPai(permissoesArray.current.filter((permissao) => !permissao.pai ? permissoesPai.push(permissao) : ''));
setPermissoesFilhas(permissoesArray.current.filter((permissao) => permissao.pai ? permissoesFilhas.push(permissao) : ''));
}
// toggles the checked property of all the children of a parent checkbox
const toggleCheckedPai = (event, idPermissaoPai) => {
const checked = event.target.checked;
setPermissoesFilhas(permissoesFilhas.map((permissaoFilha) => {
if (permissaoFilha.pai === idPermissaoPai) {
permissaoFilha['checked'] = checked;
}
return permissaoFilha;
}));
}
// toggles the checked property of a child checkbox
const toggleCheckedFilha = (event, idPermissaoFilha) => {
const checked = event.target.checked;
setPermissoesFilhas(permissoesFilhas.map((permissaoFilha) => {
if (permissaoFilha.id === idPermissaoFilha) {
permissaoFilha['checked'] = checked;
}
return permissaoFilha;
})
);
}
// checks if the parent checkbox is indeterminate
const isIndeterminate = (idPermissaoPai) => {
let filhas = permissoesFilhas.filter((permissaoFilha) => permissaoFilha.pai === idPermissaoPai);
const allChecked = filhas.every((permissaoFilha) => permissaoFilha.pai === idPermissaoPai amp;amp; permissaoFilha.checked);
return filhas.some((permissaoFilha) => permissaoFilha.pai === idPermissaoPai amp;amp; permissaoFilha.checked amp;amp; !allChecked);
}
// checks if all child checkboxes are marked
const allChildrenMarked = (idPermissaoPai) => {
let filhas = permissoesFilhas.filter((permissaoFilha) => permissaoFilha.pai === idPermissaoPai);
return filhas.every((permissaoFilha) => permissaoFilha.checked);
}
Есть какая-нибудь идея или альтернатива, которую я мог бы использовать для решения этой проблемы?