Текст типа ввода React JS теряет фокус после нажатия клавиши

#javascript #reactjs

#javascript #reactjs

Вопрос:

Демонстрация скрипки Я пытаюсь обновить массив состояний, который содержит массив объектов данных.

Состояние в конструкторе:

 this.state = {
        data: [
        { name: "Abc", age: 12 },
        { name: "Xyz", age: 11 }
      ]
    }
 

Обработчики:

 handleName(idx, e){
        const data = this.state.data.map((item, sidx) => {
            if (idx !== sidx) return item;
            return { ...item, name: e.target.value };
        });

        this.setState({ data: data });
  }

  handleAge(index, e){
        const data = this.state.data.map((item, sidx) => {
            if (idx !== sidx) return item;
            return { ...item, age: e.target.value };
        });

        this.setState({ data: data });
  }
 

Метод визуализации :

 render() {
      console.log('render');

        const Input = () => this.state.data.map((item, index) =>{
            return (
            <div>
              <input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
              <input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
            </div>
          );
        });

        return (
            <div>
             <Input/>
          </div>
        )
      }
    }
 

Я знаю, что при каждом нажатии клавиши метод рендеринга обновляет dom, что-то не так с моими элементами рендеринга.
Есть предложения?

Ответ №1:

При возврате элемента из карты вам должен быть назначен ключ, иначе новый его экземпляр будет всегда создаваться при новом рендеринге. Также вы не должны создавать компонент в рендеринге

 render() {
  console.log('render');

    return (
      <div>
         {this.state.data.map((item, index) =>{
        return (
        <div key={index}>
          <input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
          <input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
        </div>
      );
    })}
      </div>
    )
  }
}
 

Рабочая демонстрация

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

1. Это то, что я думал, но это не решает проблему: jsfiddle.net/khrismuc/vcaq782p

2. @ChrisG, вы тоже создавали новый компонент в рендеринге. либо непосредственно визуализируйте его, либо создайте компонент вне рендеринга

Ответ №2:

Потому что при каждом повторном рендеринге создается новый экземпляр компонента со значениями из состояния,

Вам нужно вывести функцию из рендеринга или просто использовать ее следующим образом

 render() {
  console.log('render');  
    return (
      <div>
         {this.state.data.map((item, index) =>{
           return (
             <div>
              <input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
              <input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
             </div>);})
         }
      </div>
    )
  }
}
 

ДЕМОНСТРАЦИЯ