Реализовать рекурсивное событие onClick в react js

#javascript #reactjs #recursion #textbox

Вопрос:

Я пытаюсь реализовать рекурсивный метод в reactjs, но только при отправке или нажатии данных.

Ниже приведен код, с которым я пытаюсь:

 import React, { Component } from "react";

class Textbox extends React.Component {
    constructor(props) {
      super(props);
      this.state = {value: ''};
      this.handleChange = this.handleChange.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }
  
    handleChange(event) {this.setState({value: event.target.value});  }
    handleSubmit(event) {
      alert('A name was submitted: '   this.state.value);
      event.preventDefault();
    }
  
    render() {
      return (
        <form onSubmit={this.handleSubmit}>
        <div> 
          <label>
            Name:
            <input type="text" value={this.state.value} onChange={this.handleChange} />
          </label>
          <input type="submit" value="React" />
        </div> 
        </form>
      );
    }
  }

export default Textbox;

 

что создает следующее представление.

Простое представление текстового поля

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

Просмотр нового текстового поля после первой отправки.

что я хочу продолжить, пока не нажму кнопку «Выход» или «Стоп», которую я могу добавить в верхнюю часть представления.

Из того, что я прочитал о рекурсивной реализации в ReactJS, мне нужно снова вызвать класс/функцию внутри рендеринга. Когда я это делаю, я думаю, что react попадает в бесконечный цикл и замораживает браузер.

то, что я попытался, — это вызвать Textbox внутри <div> <div/> метода визуализации. Подобный этому:

 .... other code lines are same
<div> 
  <label>
    Name:
    <input type="text" value={this.state.value} onChange={this.handleChange} />
  </label>
  <input type="submit" value="React" />
  <Textbox/>
</div> 
 

Как я могу создать рекурсивное текстовое поле при отправке/нажатии события в предыдущем текстовом поле?

Комментарии:

1. Рекурсивная функция требует случая остановки. В чем заключается ваше дело о прекращении?

2. У вас может быть массив, который продолжает отображать текстовую область — codesandbox.io/s/workspace-react-z9tok?file=/src/App.js

Ответ №1:

Вы могли бы сделать это так, где showNextInput предотвращает бесконечный цикл:

 class Textbox extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            showNextInput: false,
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {this.setState({value: event.target.value});  }
    handleSubmit(event) {
        console.log('submit');
        event.preventDefault();
        this.setState({ showNextInput: true });
    }

    render() {
        return (
            <>
                <form onSubmit={this.handleSubmit}>
                    <div>
                        <label>
                            Name:
                            <input type="text" value={this.state.value} onChange={this.handleChange} />
                        </label>
                        <input type="submit" value="Submit" />
                    </div>
                </form>
                { this.state.showNextInput ? <Textbox/> : null }
            </>
        );
    }
}
 

Тем не менее, ваш вариант использования выглядит как то, что вы обычно делаете с помощью

  • управление списком значений где-то,
  • добавляйте элементы по мере необходимости в свои обработчики и
  • затем отобразите список этих элементов

Вот быстрый и грязный пример:

 export class TextboxList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            values: {
                0: ''
            },
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(index, value) {
        this.setState({
            values: {
                ...this.state.values,
                [index]: value
            }
        });
    }

    handleSubmit(event) {
        event.preventDefault();
        this.setState({
            values: {
                ...this.state.values,
                [Object.keys(this.state.values).length]: '' // add new empty item to list
            }
        });

    }

    render() {
        return (
            <>
                <form onSubmit={this.handleSubmit}>
                    { Object.keys(this.state.values).map( (index) => {
                        const value = this.state.values[index];
                        return <div key={ index }>
                            <label>
                                Name:
                                <input
                                    type="text"
                                    value={ value }
                                    onChange={ (event) => this.handleChange( index, event.target.value ) }
                                />
                            </label>
                            <input type="submit" value="Submit" />
                        </div>;
                    })}
                </form>
            </>
        );
    }
}

export default Textbox;