简体   繁体   English

输入的多个参考,仅适用于最后一个

[英]multiple refs for inputs, works only last one

I'm trying to make a editable table using ref.我正在尝试使用 ref 制作可编辑的表格。

In this case I can only get last input's value through ref, but created multiple refs for it.在这种情况下,我只能通过 ref 获取最后一个输入的值,但为其创建了多个 ref。

Why is it any ideas?为什么会有任何想法?

Please let me know if you need more info about it.如果您需要更多信息,请告诉我。

import React, { useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Table = props => {
  const materials = Array(7).fill({
    a: "a",
    b: "b",
    aref: useRef(null),
    bref: useRef(null)
  });
  const handle = (index, key, ref) => {
    console.log(index, ref.current.value);
  };
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>a</th>
            <th>b</th>
          </tr>
        </thead>
        <tbody>
          {materials.map((item, index) => {
            return (
              <tr key={index}>
                <td>
                  <input
                    onChange={e => handle(index, "a", item.aref)}
                    type="text"
                    ref={item.aref}
                  />
                </td>
                <td>
                  <input
                    onChange={e => handle(index, "b", item.bref)}
                    type="text"
                    ref={item.bref}
                  />
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </>
  );
};

function App() {
  return (
    <div className="App">
      <Table />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

codesandbox: https://codesandbox.io/s/upbeat-breeze-sm7c6代码和盒子: https ://codesandbox.io/s/upbeat-breeze-sm7c6

Array.fill(value[, start[, end]]) will fill the array with value between start and end . Array.fill(value[, start[, end]])将用startend之间的value填充数组。 So, your ref is same objects in your array.因此,您的 ref 是数组中的相同对象。 Try to change your code like this:尝试像这样更改您的代码:

  // ...
  const materials = Array(7).fill(null).map(() => ({
    a: "a",
    b: "b",
    aref: useRef(null),
    bref: useRef(null)
  }))
  // ...

I did a slight modification, which should work as your expectation.我做了一个轻微的修改,这应该符合你的期望。

const Table = props => {
  const materials = Array(7);

  for (var i=0;i<materials.length;i++){
    materials[i] = {
      a: "a",
      b: "b",
      aref: React.createRef(),
      bref: React.createRef()
    };
  }

  const handle = (index, key, ref) => {
    console.log(index, ref.current.value);
  };
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>a</th>
            <th>b</th>
          </tr>
        </thead>
        <tbody>
          {materials.map((item, index) => {
            return (
              <tr key={index}>
                <td>
                  <input
                    onChange={e => handle(index, "a", item.aref)}
                    type="text"
                    ref={item.aref}
                  />
                </td>
                <td>
                  <input
                    onChange={e => handle(index, "b", item.bref)}
                    type="text"
                    ref={item.bref}
                  />
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </>
  );
};

Your problem is, you are iterating over materials array and creating your input's.您的问题是,您正在迭代materials数组并创建您的输入。 In those created input's you are adding ref .在那些创建的输入中,您正在添加ref

As there is multiple elements with same ref , react might get confuse which one to pick and in a result it is picking up last one to get the values.由于有多个元素具有相同的ref ,react 可能会混淆选择哪个元素,结果它选择最后一个来获取值。 So this indicates that react need unique ref to be used.所以这表明 react 需要使用unique ref

That is why you are getting value for last input but not for others.这就是为什么您为上次输入获得价值而不是为其他人获得价值。


As per docs ,根据文档

There are a few good use cases for refs: refs 有一些很好的用例:

  1. Managing focus, text selection, or media playback.管理焦点、文本选择或媒体播放。
  2. Triggering imperative animations.触发命令式动画。
  3. Integrating with third-party DOM libraries.与第三方 DOM 库集成。

Avoid using refs for anything that can be done declaratively.避免将 refs 用于任何可以声明性完成的事情。


So when you have onChange for every input, I think no need to use ref to get value of input.所以当你对每个输入都有onChange时,我认为不需要使用 ref 来获取输入的值。 You can directly get the values using e.target.value ,您可以使用e.target.value直接获取值,

<input onChange={e => handle(index, "a", e)} type="text" />
const handle = (index, key, e) => {
    console.log(index, e.target.value);
};

Demo演示

我曾经遇到过同样的问题,一段时间后我意识到我是在静态defaultProps创建引用,因此所有元素的所有引用都是相同的,并且会出现相同的错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM