简体   繁体   English

React - 如何在 useEffect 期间 append 将组件反应到 useRef 组件

[英]React - how to append react component to useRef component during useEffect

I would like to know if there is a way to append another react component to the useRef element?我想知道是否有办法让 append 另一个对useRef元素的反应组件?

Scenario: when the Parent 's useEffect detects the Child 's heading to be bigger than X size: add another react component.场景:当ParentuseEffect检测到Child的标题大于 X 大小时:添加另一个 react 组件。

  • I would like the implementation to be on the Parent , because in my whole app, there was only one specific case where I need to do this.我希望实现在Parent上,因为在我的整个应用程序中,只有一个特定情况需要这样做。 Therefore I did not want to modify the core Child component props.因此我不想修改核心Child组件道具。
import React, { ReactNode, useEffect, useRef } from 'react';
import { css } from 'emotion';

const someStyle = css`
   background-color: red;
`;

type ChildProp = {
    children: ReactNode;
};
const Child = React.forwardRef<HTMLHeadingElement, ChildProp>(
    ({ children }, ref) => {
        return <h1>{children}</h1>;
    },
);

const Parent = React.FunctionComponent = ()=> {
        const childRef = useRef<HTMLHeadingElement>(null);

        useEffect(() => {
            if (childRef.current && childRef.current.clientHeight > 30) {
                // append component to childRef.current
                // e.g. childRef.current.append(<div className={someStyle}>hello</div>);
            }
        }, []);

        return <Child ref={childRef}>hello world</Child>;
};

export default Parent;

You should not manually manipulate the dom.您不应该手动操作 dom。 React makes the assumption that it's the only one changing the page, so if that assumption is false it may make changes which overwrite yours, or skip changes that it doesn't realize it needs to do. React 假设它是唯一改变页面的人,所以如果这个假设是错误的,它可能会做出覆盖你的改变,或者跳过它没有意识到它需要做的改变。

Instead, you should set state, causing the component to rerender.相反,您应该设置 state,导致组件重新呈现。 Then render something that matches what you want the dom to look like.然后渲染一些与你希望 dom 看起来相匹配的东西。

const Parent = React.FunctionComponent = ()=> {
  const childRef = useRef<HTMLHeadingElement>(null);
  const [large, setLarge] = useState(false);

  useEffect(() => {
    if (childRef.current && childRef.current.clientHeight > 30) {
      setLarge(true);
    }
  }, []);

  return (
    <React.Fragment>
      <Child ref={childRef}>hello world</Child>
      {large && (<div className={someStyle}>hello</div>)}
    </React.Fragment>
  )
};

PS: If you see the screen flicker with this code, consider changing it to useLayoutEffect instead of useEffect PS:如果看到这段代码屏幕闪烁,考虑useLayoutEffect而不是useEffect

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM