[英]Unable to style component using forwardRef
我对反应还很陌生,所以我仍然了解组件的生命周期。 但这个问题让我摸不着头脑。
例如,我不明白为什么要添加“setState(10);” 导致“测试”组件的样式恢复为默认值,但<div ref={ref2}>Hi</div>
保持其样式。 (见下图)
我知道“setState(10);” 会导致重新渲染,但为什么要恢复“测试”组件的样式?
另外,请忽略调用 setState(10) 的“实际使用”——我知道它毫无意义,因为它从未被使用过,而且我知道使用“state”作为 UseEffect 依赖项可以解决这个问题。 但我遇到的主要问题是理解为什么组件的样式会恢复为默认值。
import React, { useEffect, useState, useRef } from "react";
export default function App() {
const [state, setState] = useState();
let ref1 = useRef();
let ref2 = useRef();
useEffect(() => {
console.log("useEffect called ", ref1.current);
ref1.current.style.backgroundColor = "red";
ref2.current.style.backgroundColor = "green";
setState(10);
// }, [state]);
}, []);
const Test = React.forwardRef((props, ref1) => {
console.log("test called - rendering webpage", ref1.current);
return (
<div ref={ref1} {...props}>
HI from Test{" "}
</div>
);
});
return (
<div className="App">
<Test ref={ref1} />
<div ref={ref2}>Hi</div>
</div>
);
}
控制台 output
test called - rendering webpage undefined
useEffect called <div style="background-color: red;">HI </div>
test called - rendering webpage <div style="background-color: red;">HI </div>
import React, { useEffect, useState, useRef } from "react";
export default function App() {
const [state, setState] = useState();
let ref1 = useRef();
let ref2 = useRef();
useEffect(() => {
console.log("useEffect called ", ref1.current);
ref1.current.style.backgroundColor = "red";
ref2.current.style.backgroundColor = "green";
setState(10);
// }, [ref.current]);
}, [state]);
const Test = React.forwardRef((props, ref1) => {
console.log("test called - rendering webpage", ref1.current);
return (
<div ref={ref1} {...props}>
HI from Test{" "}
</div>
);
});
return (
<div className="App">
<Test ref={ref1} />
<div ref={ref2}>Hi</div>
</div>
);
}
发生这种情况的原因是一旦您更新 state 整个组件就会重新呈现。 您的 useEffect 将仅在 componentDidMount 上运行一次,因此您获得的新参考不会更新。 要摆脱这种情况,您应该使用 state 作为 useEffect 的依赖项。
样式消失的原因是您已经在App
组件中定义了Test
组件。 这意味着每次App
呈现时,您都将定义一个名为Test
的新组件类型。 该组件的文本与前一个组件相同,但就 React 而言它是一种新类型,因此 React 被迫卸载旧组件并安装新组件。 这会清除您对旧版本所做的任何更改。
所以至少,您需要将Test
移到App
之外。 这样,组件只定义一次,不会在每次渲染时重新挂载
export default App() {
// ...
}
const Test = React.forwardRef((props, ref1) => {
// ...
})
上面应该修复重置并让您尝试使用 refs,但我强烈建议您不要使用 refs 来设置元素的样式。 Refs 是有时需要的逃生舱口,但为组件设置样式的标准方法是通过 style 道具。 如果你需要改变风格,那么你可以有一个 state 变量,让它控制风格道具。
如果您手动使用 javascript 设置ref1.current.style.backgroundColor
,react 无法知道您这样做了,因此无法将这些更改考虑在内。 在某些情况下,React 可能最终会覆盖您的更改,或者可能会跳过它没有意识到需要做的更改。
export default function App () {
const [colored, setColored] = useState(false);
useEffect(() => {
setColored(true);
}, [])
return (
<div className="App">
<Test style={colored ? { backgroundColor: "green" } : undefined} />
<div style={colored ? { backgroundColor: "red" } : undefined}>Hi</div>
</div>
);
}
// Don't really need forwardRef anymore, but i left it in
const Test = React.forwardRef((props, ref) => {
return (
<div ref={ref} {...props}>
HI from Test
</div>
);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.