0

I am retrieving DOM nodes of my child components by passing a callback into its ref prop as shown.

Parent component:

setElementRef = (name, element) => {
    if (element) {
        this.setState({
            ...this.state,
            menuItems: {
                ...this.state.menuItems,
                [name]: prop,
            },
        });
    }
};

render() {
    return <Child refCallback={(node) => this.setElementRef("child", node)} />
}

Child component:

render() {
    return (
        <div ref={this.props.refCallback}/>
}

The information in the nodes such as getBoundingClientRect() are needed. However, I am unable to setState as it exceeds the maximum update depth when multiple child components trigger the callback. Is there a way of storing multiple DOM nodes in the state, or should I avoid setting the state completely and use a class variable instead?

4

1 回答 1

1

Theoertically said, reference is not state. Therefore you should not use state to store component reference.

In your case, you just need to create object on class to keep your references (Unline setState it won't trigger re-render, and it will be accessible from within your component, or you can pass it as prop)

childRefs = {}


setElementRef = (name, element) => {
    this.childRefs.current[name] = element;
}

// ... and use it like this

someOperation = () => {
    const { child } = this.childRefs;
    if (child) {
        const rect = child.getBoundingClientRect();
    }
}

Original answer - to be used with functional components and hooks

If you need to work with references, it is recommended to use useRef (It allows you to update it's value without rerendering component) to keep actual reference, or to keep one single object, and just set properties with your reference. Then you can work with those refernces in callbacks or useEffect.

于 2020-05-19T20:51:39.450 回答