Refs for dynamically generated components in React?

半腔热情 提交于 2020-01-02 17:35:13

问题


The code below is a minimal working example to explain my problem. This code generates 3 Note components using Array.map and when you hit enter in them it empties the statically generated Note component above them using a ref to its DOM element.

What I want to do is instead have the Note you hit enter in empty itself. I think this would require generating a dynamic array containing {id, ref} for each Note, so I could pass the Note id to handleKeyDown then search the refs array for that id and use the corresponding ref to change the DOM element. But I'm having trouble figuring out how to actually do this.

I realize using refs here isn't necessary but it's just an example since my actual code is a lot longer and calls 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:


You need to store a separate ref for all your Note components and then pass back the index of the Note in focus to the handleKeyDown function

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;


来源:https://stackoverflow.com/questions/53368828/refs-for-dynamically-generated-components-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!