У меня проблема с управлением состояниями в ReactJS. Я создал компонент под названием «Шаг», который состоит из поля ввода текста и кнопки. Функция кнопки - создать «подшаг», чтобы у вас был такой структурированный список:
и так далее.
Каждый шаг имеет 2 переменные состояния: его описание (что находится внутри текстового ввода) и список его собственных подэтапов. В моем основном компоненте, в котором я создаю родительские шаги, у меня есть массив состояний, который содержит все родительские шаги (которые содержат список их подэтапов, которые содержат список их подэтапов и т. д.).
Проблема в том, что когда я пытаюсь зарегистрировать этот основной массив. Для каждого первого уровня step показывает, что у него нет описания и никаких подэтапов, хотя и есть.
Моя цель - просто зарегистрировать массив и получить все шаги (как основной шаг или внутри массива другого шага)
Вот как я добавляю шаг основного уровня в основной компонент:
export default class DynamicForm extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
actors: [],
steps: [],
systemActorAdded: false,
};
let url = "http://localhost:8080";
}
addStep = () => {
const currentSteps = this.state.steps;
currentSteps.push(new Step());
this.setState({steps: currentSteps});
};
removeStep = () => {
const steps = this.state.steps;
steps.pop();
this.setState({steps: steps});
};Это компонент Step, который должен содержать его описание и все его подшаги:
export default class Step extends Component {
constructor() {
super();
this.state = {
subSteps: [],
description: '',
};
}
createSubStep = () => {
let subSteps = this.state.subSteps;
subSteps.push(new Step());
this.setState({subSteps});
};
removeSubStep = () => {
let subSteps = this.state.subSteps;
subSteps.pop();
this.setState({subSteps});
};
handleInputChange = (event) => {
event.preventDefault();
this.setState({description: event.target.value});
};
render() {
const subSteps = this.state.subSteps.map((element, index) => {
return (
<Step key = {index}/>
)
});
return (
<div className = "text-and-button">
<input type = "text" className = "form-control animated lightSpeedIn step"
placeholder = "Wprowadź krok" onChange = {this.handleInputChange}/>
<button type = "button" className = "btn btn-success step-button animated lightSpeedIn"
onClick = {this.createSubStep}>
<i className = "fas fa-plus"/>
</button>
{this.state.subSteps.length > 0 ?
<button type = "button" className = "btn btn-danger step-button animated lightSpeedIn"
onClick = {this.removeSubStep}>
<i className = "fas fa-minus"/>
</button> : null}
<div className = "full-width">
{subSteps}
</div>
</div>
)
}
}И вот как я регистрирую содержимое массива шагов из основного компонента:
getStepsArray = () => {
let stepArray = this.state.steps;
let steps = [];
for (let step of stepArray) {
steps.push(step.state);
}
return steps;
};Обновлено: это то, что я ожидал в качестве примера вывода всей таблицы:
"steps":[
{
"description":"asd",
"subSteps":[
{
"description":"asd",
"subSteps":[
{
"description":"hello"
}
]
}
]
},
{
"description":"aaaa"
}
]
Готово, извините за неудобства
Вы не можете получить step.state, как вы это сделали. Шаг в вашем состоянии является объектом, а не самим компонентом. Возможно, вам стоит использовать refs, если вы хотите сделать что-то подобное.





Могу предложить разделить представление (рендеринг компонента) и данные.
Я бы попробовал это так: поскольку ваши подшаги кажутся связанными с основным состоянием, создайте методы добавления и удаления подшагов в основном компоненте и передайте их компоненту Step. Настройте основное состояние так, чтобы state.steps представлял собой массив объектов (шагов), каждый из которых включает подшаги.
Также отобразите подшаги в главном и передайте «подшаги» вниз как опору.
Поскольку state.description поступает из входа в компонент Step (т.е. он контролируется), вы также можете передать его обратно в основное состояние в качестве параметра. Когда вы регистрируете stepArray, вы можете перейти к подшагам как step.substeps.
Надеюсь, это поможет!
Я не уверен, что правильно понял. Вы имели в виду, что я должен сохранить все шаги (независимо от уровня) в основном массиве? Кроме того, не знаю, как должно выглядеть отображение. Я должен поддерживать иерархию подшагов, поэтому для меня было естественным иметь ее, как сейчас, и просто распечатать весь массив один раз.
Я добавил ожидаемый результат к своему вопросу, чтобы уточнить, что я хочу получить
В общем, вы хотите разделить представление (рендеринг) и данные, если только это не контролируемый компонент, в котором входные данные отражают состояние. Вы добавляете данные в компонент Step, которыми лучше управлять в основном компоненте. Кроме того, чтобы очистить его, вы можете захотеть еще больше отделить свое представление, чтобы Step визуализировал родительский шаг, а затем, возможно, даже «Substep1» и «Substep2» с учетом уровней. Дайте компоненту Step кнопку «добавить», дайте Substep1 кнопку «добавить» и «удалить». Подшаг 2 получает кнопку «удалить». Добавить добавит подшаг на уровень ниже. Удалить удалит сам шаг.
Отделение логики от представления - это то, что я делал бы с самого начала, но, поскольку я все еще новичок в React, я не знал, как это сделать.
В настоящее время у всех шагов есть кнопка «добавить», поскольку у каждого шага могут быть свои подшаги. Кнопка «удалить» привязана к родительскому шагу и удаляет его подэтапы один за другим снизу (всплывающее окно). Основная идея состоит в том, что каждый шаг потенциально может иметь бесконечное количество подшагов, поэтому я не вижу, как здесь можно использовать идею «Подшага1» и «Подшага2». Я, конечно, чего-то не хватает, но это может быть языковой барьер, так как английский не мой основной язык
Пожалуйста, включите ваш код в текстовом формате, а не в виде изображений.