Ссылка на динамически генерируемые компоненты в React? - PullRequest
0 голосов
/ 19 ноября 2018

Приведенный ниже код является минимальным рабочим примером, объясняющим мою проблему. Этот код генерирует 3 компонента Note, используя Array.map, и когда вы нажимаете enter, он очищает статически сгенерированный компонент Note над ними, используя ссылку на свой элемент DOM.

Вместо этого я хочу, чтобы записка, в которую вы нажали, была пуста. Я думаю, что для этого потребуется создать динамический массив, содержащий {id, ref} для каждой заметки, поэтому я мог бы передать идентификатор заметки в handleKeyDown, а затем выполнить поиск в массиве refs для этого идентификатора и использовать соответствующий ref для изменения элемента DOM. Но мне трудно понять, как на самом деле это сделать.

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

import React, { Component } from "react";
import "./App.css";

class App extends Component {
  constructor() {
    super();
    this.notes = [
      { text: "Hello world 1", id: 1 },
      { text: "Hello world 2", id: 2 },
      { text: "Hello world 3", id: 3 }
    ];
    this.ref = React.createRef();
  }

  handleKeyDown = event => {
    if (event.key === "Enter") {
      event.preventDefault();
      this.ref.current.textContent = "";
    }
  };

  render() {
    return (
      <div>
        <Note
          text={"StaticNote"}
          key={0}
          id={0}
          handleKeyDown={this.handleKeyDown}
          innerRef={this.ref}
        />
        {this.notes.map(note => (
          <Note
            text={note.text}
            key={note.id}
            id={note.id}
            handleKeyDown={this.handleKeyDown}
          />
        ))}
      </div>
    );
  }
}

class Note extends Component {
  render() {
    return (
      <p
        ref={this.props.innerRef}
        contentEditable
        onKeyDown={this.props.handleKeyDown}
      >
        {this.props.text}
      </p>
    );
  }
}

export default App;

1 Ответ

0 голосов
/ 19 ноября 2018

Вам необходимо сохранить отдельную ссылку для всех ваших компонентов Note, а затем передать обратно индекс Note в фокусе в функцию handleKeyDown

import React, { Component } from "react";
import "./App.css";

class App extends Component {
  constructor() {
    super();
    this.notes = [
      { text: "Hello world 1", id: 1, ref: React.createRef() },
      { text: "Hello world 2", id: 2, ref: React.createRef() },
      { text: "Hello world 3", id: 3, ref: React.createRef() }
    ];
  }

  handleKeyDown = (event, index) => {
    if (event.key === "Enter") {
      event.preventDefault();
      this.notes[index].ref.current.textContent = "";
    }
  };

  render() {
    return (
      <div>
        <Note
          text={"StaticNote"}
          key={0}
          id={0}
          handleKeyDown={this.handleKeyDown}
          innerRef={this.ref}
        />
        {this.notes.map((note, index) => (
          <Note
            index={index}
            innerRef = {note.ref}
            text={note.text}
            key={note.id}
            id={note.id}
            handleKeyDown={this.handleKeyDown}
          />
        ))}
      </div>
    );
  }
}

class Note extends Component {
  render() {
    return (
      <p
        ref={this.props.innerRef}
        contentEditable
        onKeyDown={(e) => this.props.handleKeyDown(this.props.index)}
      >
        {this.props.text}
      </p>
    );
  }
}

export default App;
...