【问题标题】:How can you make a createRef/useRef not target the last value. But rather go to where its suppose to如何使 createRef/useRef 不针对最后一个值。而是去它应该去的地方
【发布时间】:2019-11-12 20:04:30
【问题描述】:

除了最后添加的内容之外,无法使用 useRef/createRef 来获取任何其他 div。当单击按钮时,我怎样才能做到这一点,div 的引用发生了变化。

我已经尝试过 useRef 和 createRef。因为我想创建一个新的 ref 实例,所以我更多地研究了 createRef 而不是 useRef。 我也玩过useEffect。但我的解决方案并没有帮助我解决我最大的问题

我制作了一个包含 3 个组件的小项目,以帮助您理解我要解释的内容。

我还有一个包含模拟数据的数据库 -> 在我的实际项目中,这不是问题。它是一个包含对象的数组。 [{'id':'1', 'name':'first'},...]

主要:

const MainComponent = () => {
    const dataRef = React.createRef(null) 

    React.useEffect (() => {
        if(dataRef && dataRef.current){
            dataRef.current.scrollIntoView({ behavior:'smooth', block:'start' })
       }
    },[dataRef])

    const _onClick = (e) => {
        dataRef.current.focus(); 
    }

    return(
        <>
        {data && data.map((entry, index) =>{
            return <ButtonList 
                key={index}
                entry={entry}
                onClick={_onClick}
            /> 
        })}

        {data && data.map((entry, index) =>{
            return <ListingAllData  
                key={index}
                dataRef={dataRef}
                entry={entry}
                index={index}/>
        })}
        </>
    )
}

按钮组件

const ButtonList = ({ entry, onClick }) => {
    return <button onClick={onClick}>{entry.name}</button>
}

列表数据组件

const ListingAllData = (props) => {
    const {entry, dataRef } = props; 
    return (
        <div ref={dataRef}>
            <p>{entry.id}</p>
            <p>{entry.name}</p>
        </div>
    );
}

我已经控制台记录了 data.current,它只获取最后一个元素。我希望它会为我点击的按钮获取那个。

【问题讨论】:

    标签: reactjs reference buttonclick use-effect


    【解决方案1】:

    感谢 Janiis 的回答,我的解决方案是:

    在主组件中

    ...
      const refs = data.reduce((acc, value) => {
        acc[value.id] = React.createRef();
        return entry;
      }, {});
    
      const _onClick = id => {
        refs[id].current.scrollIntoView({
          behavior: 'smooth', 
          block: 'start'
        }); 
      }
    ....
    

    然后我将它传递给孩子并像这样引用

    <div ref={refs[entry.id]}>
    

    【讨论】:

      【解决方案2】:

      我认为这里的主要思想是为每个元素(引用数组)创建动态引用,这就是为什么在应用渲染时只选择最后一个。

      const MainComponent = () => {
        const dataRefs = [];
      
        data.forEach(_ => {
          dataRefs.push(React.createRef(null));
        });
      
        const _onClick = (e, index) => {
          dataRefs[index].current.focus();
          dataRefs[index].current.scrollIntoView({
            behavior: "smooth",
            block: "start"
          });
        };
      
        return (
          <>
            {data &&
              data.map((entry, index) => {
                return (
                  <ButtonList
                    key={index}
                    entry={entry}
                    onClick={e => _onClick(e, index)}
                  />
                );
              })}
      
            {data &&
              data.map((entry, index) => {
                return (
                  <>
                    <ListingAllData
                      key={index}
                      dataRef={dataRefs[index]}
                      entry={entry}
                      index={index}
                    />
                  </>
                );
              })}
          </>
        );
      };
      

      在代码沙箱中创建了工作示例。

      https://codesandbox.io/s/dynamic-refs-so25v

      【讨论】:

      • 我认为解决方案是动态的。我今天解决了它,但比你做的更笨拙。谢谢!
      猜你喜欢
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 2021-08-09
      • 1970-01-01
      • 2014-03-29
      • 2011-09-12
      相关资源
      最近更新 更多