React JS useState Multi-level Data
У меня вопрос по поводу setState React.
Например, у меня есть эти данные
data_menus = [
{
id: 1,
title: "Title",
preview: '../img/',
pages: [
{
id: 1,
type: 'first page',
background: '../img/',
components: []
},
{
id: 2,
type: 'Second Page',
background: '../img/',
components: []
}
],
}
]
Я пытаюсь установить значение в массив components, но это не работает. при этом вторая страница удаляется.
setCurrentState({
...currentState,
pages: [{...currentState.pages[0], components:[...currentState.pages[0].components,{
id: 1,
type: '',
}]}]
})
я пробую добавить
{
id: 1,
type: ''
}
Нужно оставить все данные без изменения внести новые только в components[]
Вот так :
data_menus = [
{
id: 1,
title: "Title",
preview: '../img/',
pages: [
{
id: 1,
type: 'first page',
background: '../img/',
components: [
0: { id:1 , type: ''}
]
},
{
id: 2,
type: 'Second Page',
background: '../img/',
components: [
0: { id:1 , type: ''}
]
}
],
}
]
Подскажите, пожалуйста, как это сделать. Спасибо!
Ответы (1 шт):
Автор решения: Sire IMPACTUS
→ Ссылка
setCurrentState(previousState => {
const clone = { ...previousState };
clone.pages[0].components.push({
id: 1,
type: ''
});
return clone;
});
Первый аргумет функции стейта - актуальное значение стейта. Вообще, лучше такие данные не хранить в стейте, особенно если планируется расширять их количество, т.к. стейт лучше работает с простыми типами данных.
PS: Почему-то useEffect не подключался, поэтому сделал через таймер.
let cancel = false;
function App() {
const [state, setState] = React.useState([{
id: 1,
title: "Title",
preview: '../img/',
pages: [{
id: 1,
type: 'first page',
background: '../img/',
components: []
},
{
id: 2,
type: 'Second Page',
background: '../img/',
components: []
}
],
}])
if (cancel === false) {
setTimeout(() => {
cancel = true;
setState(previousState => {
const clone = { ...previousState
};
clone[0].pages[0].components.push({
id: 1,
type: ''
});
return clone;
});
}, 3000)
}
console.log(state)
return null
}
const domContainer = document.querySelector('#root');
const root = ReactDOM.createRoot(domContainer);
root.render( < App / > );
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>