gpt4 book ai didi

javascript - 我们如何知道 React 的 ref.current 值何时发生了变化?

转载 作者:行者123 更新时间:2023-12-01 15:30:27 72 4
gpt4 key购买 nike

通常,有了 Prop ,我们可以写

componentDidUpdate(oldProps) {
if (oldProps.foo !== this.props.foo) {
console.log('foo prop changed')
}
}

为了检测 Prop 变化。

但是如果我们使用 React.createRef() ,我们如何检测 ref 何时更改为新组件或 DOM 元素? React 文档并没有真正提及任何内容。

即,

class Foo extends React.Component {
someRef = React.createRef()

componentDidUpdate(oldProps) {
const refChanged = /* What do we put here? */

if (refChanged) {
console.log('new ref value:', this.someRef.current)
}
}

render() {
// ...
}
}

我们是否应该自己实现某种旧值的东西?

即,

class Foo extends React.Component {
someRef = React.createRef()
oldRef = {}

componentDidMount() {
this.oldRef.current = this.someRef.current
}

componentDidUpdate(oldProps) {
const refChanged = this.oldRef.current !== this.someRef.current

if (refChanged) {
console.log('new ref value:', this.someRef.current)

this.oldRef.current = this.someRef.current
}
}

render() {
// ...
}
}

这是我们应该做的吗?我原以为 React 会为此添加一些简单的功能。

最佳答案

React 文档推荐使用 callback refs检测 ref值变化。
Hook

export function Comp() {
const onRefChange = useCallback(node => {
if (node === null) {
// DOM node referenced by ref has been unmounted
} else {
// DOM node referenced by ref has changed and exists
}
}, []); // adjust deps

return <h1 ref={onRefChange}>Hey</h1>;
}
useCallback习惯于 prevent double calling带有 null 的 ref 回调和元素。
您可以 trigger re-renders通过使用 useState 存储当前 DOM 节点来进行更改:
const [domNode, setDomNode] = useState(null);
const onRefChange = useCallback(node => {
setDomNode(node); // trigger re-render on changes
// ...
}, []);
类组件
export class FooClass extends React.Component {
state = { ref: null, ... };

onRefChange = node => {
// same as Hooks example, re-render on changes
this.setState({ ref: node });
};

render() {
return <h1 ref={this.onRefChange}>Hey</h1>;
}
}

注: useRef 不通知 ref变化。还有 no luckReact.createRef()/对象引用。
这是一个测试用例,在触发 onRefChange 时删除并重新添加一个节点打回来 :

const Foo = () => {
const [ref, setRef] = useState(null);
const [removed, remove] = useState(false);

useEffect(() => {
setTimeout(() => remove(true), 3000); // drop after 3 sec
setTimeout(() => remove(false), 5000); // ... and mount it again
}, []);

const onRefChange = useCallback(node => {
console.log("ref changed to:", node);
setRef(node); // or change other state to re-render
}, []);

return !removed && <h3 ref={onRefChange}>Hello, world</h3>;
}

ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.1/umd/react.production.min.js" integrity="sha256-vMEjoeSlzpWvres5mDlxmSKxx6jAmDNY4zCt712YCI0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.1/umd/react-dom.production.min.js" integrity="sha256-QQt6MpTdAD0DiPLhqhzVyPs1flIdstR4/R7x4GqCvZ4=" crossorigin="anonymous"></script>

<script> var {useState, useEffect, useCallback} = React</script>

<div id="root"></div>

关于javascript - 我们如何知道 React 的 ref.current 值何时发生了变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55838351/

72 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com