React useEffect hook с предупреждением react-hooks / excustive-deps
Я конвертирую код, который использовал componentDidMount/Update/Unmount
жизненный цикл React Hooks и продолжайте сталкиваться с react-hooks/exhaustive-deps
в консоли как предупреждение.
Наш новый код, похоже, работает так, как задумано, и поэтому я думаю отключить эти предупреждения. Однако в случае, если я что-то пропустил, предупреждения указаны в приведенном ниже коде.
Старый componentDidMount/Update/Unmount
код
state = {
container: canUseDOM ? createContainer(this.props.zIndex) : undefined,
portalIsMounted: false,
};
componentDidUpdate(prevProps: Props, prevState: State) {
const { container } = this.state;
const { zIndex } = this.props;
if (container && prevProps.zIndex !== zIndex) {
const newContainer = createContainer(zIndex);
getPortalParent().replaceChild(container, newContainer);
this.setState({ container: newContainer });
} else if (!prevState.container && container) {
getPortalParent().appendChild(container);
}
}
componentDidMount() {
const { container } = this.state;
const { zIndex } = this.props;
if (container) {
getPortalParent().appendChild(container);
} else {
const newContainer = createContainer(zIndex);
this.setState({ container: newContainer });
}
this.setState({
portalIsMounted: true,
});
firePortalEvent(PORTAL_MOUNT_EVENT, Number(zIndex));
}
componentWillUnmount() {
const { container } = this.state;
const { zIndex } = this.props;
if (container) {
getPortalParent().removeChild(container);
const portals = !!document.querySelector(
'body > .portal-container > .portal',
);
if (!portals) {
getBody().removeChild(getPortalParent());
}
}
firePortalEvent(PORTAL_UNMOUNT_EVENT, Number(zIndex));
}
Новый код React Hooks
const [container, setContainer] = useState(canUseDOM ? createContainer(zIndex) : undefined);
const [portalIsMounted, setPortalIsMounted] = useState(false);
useEffect(() => {
if (container) {
const newContainer = createContainer(zIndex);
getPortalParent().replaceWith(container, newContainer);
setContainer(newContainer);
}
}, [zIndex]);
useEffect(() => {
if (container) {
getPortalParent().appendChild(container);
}
}, [container]);
useEffect(() => {
if (container) {
getPortalParent().appendChild(container);
} else {
const newContainer = createContainer(zIndex);
setContainer(newContainer);
}
setPortalIsMounted(true);
firePortalEvent(PORTAL_MOUNT_EVENT, Number(zIndex));
}, []);
useEffect(() => {
if (container) {
getPortalParent().removeChild(container);
const portals = !!document.querySelector(
'body > .portal-container > .portal'
);
if (!portals) {
getBody().removeChild(getPortalParent());
}
}
firePortalEvent(PORTAL_UNMOUNT_EVENT, Number(zIndex));
}, []);
1 ответ
Здесь вы используете контейнер в своем useEffect, однако, поскольку вы также устанавливаете состояние контейнера в этом эффекте, вы не можете поместить его в качестве зависимости, иначе вы получите бесконечный цикл (эффект будет запускаться каждый раз при вызове setContainer).
Я думаю, это подходящее время для использования // eslint-disable-line
useEffect(() => {
if (container) {
const newContainer = createContainer(zIndex);
getPortalParent().replaceWith(container, newContainer);
setContainer(newContainer);
}
// eslint-disable-line
}, [zIndex]);
Могут быть и другие примеры, но вы можете понять, какие useEffects и какие зависимости требуют.