#reactjs #react-hooks #use-state
#reactjs #реагирующие хуки #использование-состояние
Вопрос:
Я столкнулся с проблемой, из-за которой react не распознает изменения, которые я внес в отношении правильности использования вложенного объекта useState, и, следовательно, не выполняет повторный рендеринг компонента.
В данном случае при разрешении пользователя.данные и разрешения.данные. Я не в первый раз сталкиваюсь с такой проблемой, что не так с моим кодом?
Вот пример:
const [userPermission, setUserPermission] = useState({
loading: false,
data: [],
selectedRows: [],
selectedRowKeys: {},
});
const [permission, setPermission] = useState({
loading: false,
data: [],
pagination: {
current: 1,
pageSize: 10,
total: 0,
position: ['topRight' as const],
},
selectedRows: [],
selectedRowKeys: {},
});
async function handleAddPermission(): Promise<any> {
if (context === 'menus') {
// const params = {
// menusIds: permission.selectedRowKeys,
// funcsIds: [],
// };
// const response = await addPermission(userId, params);
const currentUserPermissions = { ...userPermission };
const currentPermissions = { ...permission };
const concat = currentUserPermissions.data.concat(
permission.selectedRows,
);
// data upadate
setUserPermission({ ...userPermission, data: concat });
permission.selectedRows.map((selected: any) => {
const findSelectedIndex = permission.data.findIndex(
(data: any) => data.id === selected.id,
);
if (findSelectedIndex !== -1) {
currentPermissions.data.splice(findSelectedIndex, 1);
}
});
// data doesn't upadate
setPermission(currentPermissions);
}
}
return (
<>
<Collapse accordion defaultActiveKey="1">
<Panel header={userPermissionTitle} key="1">
<Table
dataSource={userPermission.data}
columns={userPermissionColumns}
pagination={false}
loading={userPermission.loading}
sortDirections={['ascend', 'descend', 'ascend']}
// rowKey={record => record.id}
/>
</Panel>
<Panel header={permissionTitle} key="2">
<SelectedContainer>
<p> {`${permission.selectedRows.length} selecionados`} </p>
<Button onClick={() => handleAddPermission()} size="small">
Adicionar ao usuário
</Button>
</SelectedContainer>
<Table
dataSource={permission.data}
columns={permissionColumns}
onChange={handlePermissionTable}
pagination={permission.pagination}
loading={permission.loading}
sortDirections={['ascend', 'descend', 'ascend']}
rowSelection={{
...PermissionsRowSelection,
}}
rowKey={(record: any) => record.id}
/>
</Panel>
</Collapse>
</>
);
Ответ №1:
Попробуйте поместить хук useEffect вокруг UserPermission.данные и посмотрите, попадете ли вы после изменения состояния. Если это произойдет, то react распознает изменение состояния. Вместо использования useState вы можете использовать useReducer.
useReducer обычно предпочтительнее useState, когда у вас сложная логика состояния, которая включает в себя несколько вложенных значений или когда следующее состояние зависит от предыдущего. https://reactjs.org/docs/hooks-reference.html#usereducer
Ответ №2:
Вы можете обновлять вложенные объекты, подобные этому, внутри вашего обработчика ввода / обновления. Оператор распространения создает только мелкие копии. однако это создает клон нашего объекта, сохраняющий вложенные поля.
// InitialValue is your current state
const initialValue = {answer: {
highest:42,
flag:true
}};
let newValue = JSON.stringify(initialValue);
newValue = JSON.parse(newValue)
newValue.answer.flag = false;
//You can provide this new value to your setState()
console.log(newValue)