我正在尝试在发生更改时更改元素的左样式属性,但我的代码不起作用,您知道为什么吗?
函数组件:
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>
答案 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 就像您在此处的问题中所写的一样。