尝试在反应中使用效果,但我的代码不起作用

时间:2021-04-02 15:21:26

标签: reactjs typescript react-native

我正在尝试在发生更改时更改元素的左样式属性,但我的代码不起作用,您知道为什么吗?

函数组件:

const Link: React.FunctionComponent<{ name: string, href?: string }> = function ({ name, href }) {
          const filteredName = name.toLowerCase().trim().split(" ").join("")
          var res = 0
          useEffect(()=>{
               function handleResize() {

                    const w = globalThis.outerWidth
                    const h = globalThis.outerHeight
                    let index = 0
                    for (let elem = 0;elem<allDataElems.length;elem++) {
                         if (allDataElems[elem] === name) {
                              index = elem + 1
                              break
                         }
                    }
                    var elSize = null
                    try {
                         elSize = ulEl.current!.scrollTop + (ulEl.current!.firstElementChild!.scrollHeight * (index)) + index * 32 - 250
                    } catch {
                         elSize = 0
                    }
                    return (w*28*3/1000)*(elSize/h)
               }
               res = handleResize()
          })
          return <li style={{top: "20px",left: res + "px"}}><Anchor href={href || `/${name.replace(/ /g, "_")}`}><a onClick={() => closeNav()} onMouseOver={() => setHovering(filteredName as keyof typeof datas)}>{name}</a></Anchor></li>
     }

我在哪里使用它:

    <Link name="Home" href="/"></Link>
    <Link name="Project"></Link>
    <Link name="Team"></Link>
    <Link name="Description"></Link>
    <Link name="Human Practices"></Link>
    <Link name="Judging Form"></Link>
    <Link name="Gallery"></Link>

3 个答案:

答案 0 :(得分:0)

您不应在与函数组件不同的上下文中使用 useRef。您可以阅读 official documentation 中的所有规则。

在您的情况下,您可以通过使用 Object 创建单个 ref 并将元素引用存储为键/值对来解决它,如下所示:

const Navbar = function () {
  const linkRefs = useRef<{[key: string]: HTMLLIElement}>({});

  useEffect(() => {
    Object.values(linkRefs).forEach(element => {
      // use element to access each element
    });
  });

  return (
    <div>
      <Link ref={linkRefs.home} name="Home" href="/"></Link>
      <Link ref={linkRefs.projects} name="Projects" href="/projects"></Link>
      ...
    </div>
  );
};

答案 1 :(得分:0)

顺便说一下,我找到了答案,只是在 useEffect 中生成了所有链接,这让我的工作变得更加轻松:

useEffect(() => {
          const list = []
          for (var i=0;i<datas.length;i++){
               const t = datas[i].title
               const res = handleResize(i + 1)
               list.push(<li ref={resl[i + 1]} style={{top: "20px",left: res + "px"}}><Anchor href={/*datas[i].content?][1]*/ `/${t.replace(/ /g, "_")}`}><a onClick={() => closeNav()} onMouseOver={() => setHovering(i)}>{t}</a></Anchor></li>)
          }

          setLinks(list)
          console.log(datas[hovering])
     })

然后我将它返回到另一个 html 元素中。

答案 2 :(得分:0)

对于这种事情,我通常使用 useMemo 而不是 useEffect。

const [change, setChange] = useState() //whatever your onclick value sets
const res = useMemo(() => {

                const w = globalThis.outerWidth
                const h = globalThis.outerHeight
                let index = 0
                for (let elem = 0;elem<allDataElems.length;elem++) {
                     if (allDataElems[elem] === name) {
                          index = elem + 1
                          break
                     }
                }
                var elSize = null
                try {
                     elSize = ulEl.current!.scrollTop + (ulEl.current!.firstElementChild!.scrollHeight * (index)) + index * 32 - 250
                } catch {
                     elSize = 0
                }
                return (w*28*3/1000)*(elSize/h)
        
      }, [change]) //dependency. whatever that will retrigger res to get new value

您可以使用 res 就像您在此处的问题中所写的一样。