如何对带有钩子的元素数组使用多个引用? [英] How can I use multiple refs for an array of elements with hooks?

查看:55
本文介绍了如何对带有钩子的元素数组使用多个引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,我可以将refs用于单个元素,例如:

As far as I understood I can use refs for a single element like this:

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (
    <div>
      <div ref={elRef} style={{ width: "100px" }}>
        Width is: {elWidth}
      </div>
    </div>
  );
};

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

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>

如何为元素数组实现此功能?显然不是这样:(即使我没有尝试过,我也知道:)

How can I implement this for an array of elements? Obviously not like that: (I knew it even I did not try it:)

const { useRef, useState, useEffect } = React;

const App = () => {
  const elRef = useRef();
  const [elWidth, setElWidth] = useState();

  useEffect(() => {
    setElWidth(elRef.current.offsetWidth);
  }, []);

  return (
    <div>
      {[1, 2, 3].map(el => (
        <div ref={elRef} style={{ width: `${el * 100}px` }}>
          Width is: {elWidth}
        </div>
      ))}
    </div>
  );
};

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

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>

我见过,因此也见过

I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.

推荐答案

ref最初只是{ current: null }对象. useRef在组件渲染之间保留对此对象的引用. current值主要用于组件引用,但可以容纳任何内容.

A ref is initially just { current: null } object. useRef keeps the reference to this object between component renders. current value is primarily intended for component refs but can hold anything.

在某个时候应该有一系列的引用.如果各渲染之间的数组长度可能不同,则数组应相应缩放:

There should be an array of refs at some point. In case the array length may vary between renders, an array should scale accordingly:

  const arrLength = arr.length;
  const [elRefs, setElRefs] = React.useState([]);

  React.useEffect(() => {
    // add or remove refs
    setElRefs(elRefs => (
      Array(arrLength).fill().map((_, i) => elRefs[i] || createRef())
    ));
  }, [arrLength]);

  return (
    <div>
      {arr.map((el, i) => (
        <div ref={elRefs[i]} style={...}>...</div>
      ))}
    </div>
  );

可以通过展开useEffect并将useState替换为useRef来优化这段代码,但应注意,在渲染函数中产生副作用通常被认为是一种不好的做法:

This piece of code can be optimized by unwrapping useEffect and replacing useState with useRef but it should be noted that doing side effects in render function is generally considered a bad practice:

  const arrLength = arr.length;
  const elRefs = React.useRef([]);

  if (elRefs.current.length !== arrLength) {
    // add or remove refs
    elRefs.current = Array(arrLength).fill().map((_, i) => elRefs.current[i] || createRef());
  }

  return (
    <div>
      {arr.map((el, i) => (
        <div ref={elRefs.current[i]} style={...}>...</div>
      ))}
    </div>
  );

这篇关于如何对带有钩子的元素数组使用多个引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆