在React中动态生成的组件的引用?

时间:2018-11-19 05:32:32

标签: javascript reactjs dom ref

以下代码是解释我的问题的最小工作示例。这段代码使用Array.map生成3个Note组件,当您按Enter键时,它们将使用对DOM元素的引用清空它们上方的静态生成的Note组件。

我想做的是改为将您点击的便笺输入为空。我认为这需要为每个Note生成一个包含{id,ref}的动态数组,因此我可以将Note id传递给handleKeyDown,然后在refs数组中搜索该id并使用相应的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 :(得分:6)

您需要为所有Note组件存储一个单独的ref,然后将焦点集中的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;