1

我有一个 React 组件,它接收一个具有动态生成一些子组件的属性的对象。在生成这些新组件时,我需要为每个组件创建一个 ref,但React.createRef()返回currentnull.

这是我所做的:

const source = {
   component1: {
      name: 'Component 1',
      active: true
   },
   component2: {
      name: 'Component 2',
      active: true
   },
   component3: {
      name: 'Component 3',
      active: false
   }
}

那么这是主要的组成部分:

function MyComp(props) {
   const {source} = props;

   const refs = {};

   function makeComps() {
      const newComps = [];
      Object.keys(source).forEach(x => {
         const myRef = React.createRef();
         refs[x] = myRef;
         newComps.push(
         <div ref={myRef}>
           <div>Name</div>
           <div>{source[x].name}</div>

           <div>Active</div>
           <div>{source[x].active ? 'Yes' : 'No'}</div>
         </div>);
      });
      return newComps;
   }

   return (
      <>
        <strong>{'Brand new components'}</strong>
        {source && makeComps()}
        {!source && <div>Nothing new</div>}
      </>
   );
}

然后,当我尝试访问refs它时,它会返回:

{
   component1: {current: null},
   component2: {current: null},
   component3: {current: null}
}

我需要这些参考来window.scrollTo在某些情况下做出决定。根据 React 官方文档,我没有做任何奇怪的事情。我也尝试过React.useRef(),但没有。

这是我如何达到这个参考:

const myRef = refs.component3;
window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop });

我该如何解决这个问题?我在这里想念什么?

4

2 回答 2

2

我假设您在第一次渲染完成之前尝试访问它们。在这种情况下,您的组件没有安装。确保它是,使用useEffect钩子。在这里了解更多

function MyComp({ source, ...props }) {
  const refs = {};

  function makeComps() {
    const newComps = [];

    Object.keys(source).forEach((x, idx) => {
      const myRef = React.createRef();
      refs[x] = myRef;

      newComps.push(
        <div key={idx} ref={myRef}>
          <div>Name</div>
          <div>{source[x].name}</div>
          <div>Active</div>
          <div>{source[x].active ? 'Yes' : 'No'}</div>
        </div>
      );
    });

    return newComps;
  }

  useEffect(() => {
    // here, your component did mount

    // try to access component1 using the optional
    // chaining feature of JavaScript
    console.log(refs.component1?.current);
  }, [refs]);

  return (
    <>
      <strong>{'Brand new components'}</strong>
      {source && makeComps()}
      {!source && <div>Nothing new</div>}
    </>
  );
}
于 2020-03-27T21:11:19.310 回答
-1

好吧,这里的Kluddizz部分地给了我解决方案,虽然他的解决方案没有为我的问题提供正确的答案,但他为我指出了正确的解决方案。挂钩救援:

useEffect(() => {
   if (refs.component3 && refs.component3.current) {
      //do the magic
   }
});

他的评论:

您需要确保在第一次渲染后访问 refs。这很简单,因为 React 在第一次渲染期间不会解析 refs。

是正确解决方案的切入点。

于 2020-03-27T23:55:51.820 回答