输入多个引用,仅可使用最后一个

时间:2019-07-15 05:07:27

标签: reactjs

我正在尝试使用ref制作可编辑表格。

在这种情况下,我只能通过ref获取最后输入的值,但为此创建了多个refs。

为什么有什么主意?

如果您需要更多信息,请告诉我。

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

4 个答案:

答案 0 :(得分:3)

Array.fill(value[, start[, end]])将在valuestart之间用end填充数组。因此,您的引用是数组中的相同对象。尝试像这样更改代码:

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

答案 1 :(得分:2)

我做了一些细微的修改,应该可以满足您的期望。

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>
    </>
  );
};

答案 2 :(得分:1)

您的问题是,您要遍历materials数组并创建输入。在这些创建的输入中,您要添加ref

由于存在多个具有相同ref的元素,因此react可能会混淆选择哪个元素,结果它会选择最后一个元素以获取值。因此,这表明需要使用unique ref

这就是为什么您要为最后的输入获得价值,而不是为其他输入获得价值。


根据docs

  

裁判有一些很好的用例:

     
      
  1. 管理焦点,文本选择或媒体播放。
  2.   
  3. 触发命令性动画。
  4.   
  5. 与第三方DOM库集成。
  6.   

避免将refs用于声明性的操作。


因此,当每个输入都有onChange时,我认为不需要使用ref来获取输入值。您可以使用e.target.value直接获取值,

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

Demo

答案 3 :(得分:0)

一段时间后,我意识到自己正在静态defaultProps中创建引用,因此我遇到了同样的问题,因此所有元素的所有引用都相同,并且会出现相同的错误< / p>

相关问题