我们如何知道React ref.current值何时更改?

时间:2019-04-24 20:49:41

标签: javascript reactjs react-ref

通常,我们可以用道具来写

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

以检测道具变化。

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

F.e。

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() {
    // ...
  }
}

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

F.e。

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会为此提供一些简单的功能。

2 个答案:

答案 0 :(得分:17)

反应文档建议使用callback refs检测 import requests from bs4 import BeautifulSoup url0 = 'https://finance.yahoo.com/' page0 = requests.get(url0) soup0=BeautifulSoup(page0.text, 'lxml') urls=[] for link in soup0.find_all('a'): if '/news' in link.get('href'): urls.append(link.get('href')) full_urls=['https://finance.yahoo.com' + u for u in urls] 值的变化。

Hooks示例:

ref

类组件示例:

export function Foo() {
  const [ref, setRef] = useState(null);

  const onRefChange = useCallback(node => {
    // ref value changed to node
    setRef(node); // e.g. change ref state to trigger re-render
    if (node === null) { 
      // node is null, if DOM node of ref had been unmounted before
    } else {
      // ref value exists
    }
  }, []);

  return <h1 ref={onRefChange}>Hey</h1>;
}

注意useRef不会通知export class FooClass extends React.Component { state = { ref: null, ... }; onRefChange = node => { // same as Hooks example this.setState({ ref: node }); }; render() { return <h1 ref={this.onRefChange}>Hey</h1>; } } 的更改。还有no luckref /对象引用。

这是一个测试用例,它会在触发React.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"));

答案 1 :(得分:1)

strncpy()在组件状态或道具更改时被调用,因此在componentDidUpdate更改时不一定调用,因为您可以根据自己的喜好对其进行突变。

如果您要检查某个参考与以前的渲染相比是否发生了变化,则可以保留另一参考以与实际参考进行比较。

示例

ref
class App extends React.Component {
  prevRef = null;
  ref = React.createRef();
  state = {
    isVisible: true
  };

  componentDidMount() {
    this.prevRef = this.ref.current;

    setTimeout(() => {
      this.setState({ isVisible: false });
    }, 1000);
  }

  componentDidUpdate() {
    if (this.prevRef !== this.ref.current) {
      console.log("ref changed!");
    }

    this.prevRef = this.ref.current;
  }

  render() {
    return this.state.isVisible ? <div ref={this.ref}>Foo</div> : null;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));