Обновление состояния в родительском ReactJS

У меня проблема с управлением состояниями в ReactJS. Я создал компонент под названием «Шаг», который состоит из поля ввода текста и кнопки. Функция кнопки - создать «подшаг», чтобы у вас был такой структурированный список:

  • родительский шаг
    • шаг ребенка
      • ребенок-ребенок шаг
  • родительский шаг2

и так далее.

Каждый шаг имеет 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"
}

]

Пожалуйста, включите ваш код в текстовом формате, а не в виде изображений.

Tholle 08.11.2018 18:31

Готово, извините за неудобства

Chrapek 08.11.2018 18:36

Вы не можете получить step.state, как вы это сделали. Шаг в вашем состоянии является объектом, а не самим компонентом. Возможно, вам стоит использовать refs, если вы хотите сделать что-то подобное.

EQuimper 08.11.2018 18:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
3
54
2

Ответы 2

Могу предложить разделить представление (рендеринг компонента) и данные.

Я бы попробовал это так: поскольку ваши подшаги кажутся связанными с основным состоянием, создайте методы добавления и удаления подшагов в основном компоненте и передайте их компоненту Step. Настройте основное состояние так, чтобы state.steps представлял собой массив объектов (шагов), каждый из которых включает подшаги.

Также отобразите подшаги в главном и передайте «подшаги» вниз как опору.

Поскольку state.description поступает из входа в компонент Step (т.е. он контролируется), вы также можете передать его обратно в основное состояние в качестве параметра. Когда вы регистрируете stepArray, вы можете перейти к подшагам как step.substeps.

Надеюсь, это поможет!

Я не уверен, что правильно понял. Вы имели в виду, что я должен сохранить все шаги (независимо от уровня) в основном массиве? Кроме того, не знаю, как должно выглядеть отображение. Я должен поддерживать иерархию подшагов, поэтому для меня было естественным иметь ее, как сейчас, и просто распечатать весь массив один раз.

Chrapek 08.11.2018 19:26

Я добавил ожидаемый результат к своему вопросу, чтобы уточнить, что я хочу получить

Chrapek 08.11.2018 19:31

В общем, вы хотите разделить представление (рендеринг) и данные, если только это не контролируемый компонент, в котором входные данные отражают состояние. Вы добавляете данные в компонент Step, которыми лучше управлять в основном компоненте. Кроме того, чтобы очистить его, вы можете захотеть еще больше отделить свое представление, чтобы Step визуализировал родительский шаг, а затем, возможно, даже «Substep1» и «Substep2» с учетом уровней. Дайте компоненту Step кнопку «добавить», дайте Substep1 кнопку «добавить» и «удалить». Подшаг 2 получает кнопку «удалить». Добавить добавит подшаг на уровень ниже. Удалить удалит сам шаг.

Sarah Elizabeth Waldie 08.11.2018 19:55

Отделение логики от представления - это то, что я делал бы с самого начала, но, поскольку я все еще новичок в React, я не знал, как это сделать.

Chrapek 08.11.2018 21:52

В настоящее время у всех шагов есть кнопка «добавить», поскольку у каждого шага могут быть свои подшаги. Кнопка «удалить» привязана к родительскому шагу и удаляет его подэтапы один за другим снизу (всплывающее окно). Основная идея состоит в том, что каждый шаг потенциально может иметь бесконечное количество подшагов, поэтому я не вижу, как здесь можно использовать идею «Подшага1» и «Подшага2». Я, конечно, чего-то не хватает, но это может быть языковой барьер, так как английский не мой основной язык

Chrapek 08.11.2018 21:58

Другие вопросы по теме