zoukankan      html  css  js  c++  java
  • Ref in React

    some little tech note about React and AntD

    Let's talk a little about ref

    • basic usage example, we refer to the Dom. we prefer the sample1
    // in ts
    const refSample1 = React.useRef<HTMLDivElement>();
    const refSample2 = React.useRef<HTMLDivElement|null>();
    
    render(){
        return (
            <>
                <div ref={refSample1}>
                    Hello I am div element
                </div>
                <div ref = {node=>{refSample2.current = node;}}>
                    Hello I am div element2
                </div>
            </>
        )
    }
    
    • customized Ref, ref is not only a dom, see this example
    //ts
    interface SampleRefProps{
        onClick:()=>void,
        wrapperElement:HTMLDivElement,
    }
    // in component1
    const SampleComponent:React.RefForwardingComponent<SampleRefProps,any>=
        (props,ref)=>{
            const divRef = React.uesRef<HTMLDivElement>();
            React.useImperativeHandle(ref,()=>({
                onClick:()=>{console.log('hello click')},
                wrapperElement:divRef.current,
            }));
        
        return (
            <>
            <div ref = {divRef}>Hello I am body</div>
            </>
        )
    }
    // in Component2
    const Demo:React.FC = ()=>{
        const ref = React.useRef<SampleRefProps>();
        return (
            <SampleComponent ref = {ref}/>
        )
    }
    
    
    • When ref.current will be updated?
      according to the offical documents refs updates Before ComponentDidMount or ComponentDidUpdate or ComponentDidUnmount, that is straightforward for Class component, but for function component, I believe it will be updated after function execution but, before React.Effects() or React.LayoutEffects().
      • I just give a summary here, for function component, the order is render > React.useImperativeHandle > useLayoutEffect > useEffect (This is parallel with Browser repaint). Bellow is a code snappit
    interface RefProps{
        element:HTMLDivElement|HTMLSpanElement|null;
    };
    
    const RefFC=React.forwardRef<RefProps,{isdiv:boolean}>(({isdiv=true},ref)=>{
        const domRef = React.useRef<HTMLSpanElement|HTMLDivElement>(null);
        // here just for demo, we can attach ref to dom directlly
        React.useImperativeHandle(ref,()=>{
            console.log(`useImperativeHandle executed`)
            return {
                element:domRef.current,
            };        
        })
        React.useEffect(()=>{
            console.log('effect of RefFC execution');
        })
        console.log(`befrore redner execution of RefFC`);
        return (
            <>
            {
                isdiv&&<div ref={domRef as any}>Hello I am div</div>
            }
            {
                !isdiv&&<span ref={domRef as any}>Hello I am span</span>
            }
            </>
        );
    })
    
    const RefDemo:React.FC=()=>{
        const refSample1 = React.useRef<HTMLDivElement>(null);
        const refSample2 = React.useRef<RefProps>(null);
        const [isdiv,setIsdiv]=React.useState<boolean>(true);
        React.useEffect(()=>{
            console.log(`This is Effect,refSample1 ${refSample1.current}`);
            console.log(`This is Effect,refSample2 ${refSample2.current?.element}`);
        });
        React.useLayoutEffect(()=>{
            console.log(`This is LayoutEffect:refSample1 ${refSample1.current}`);
            console.log(`This is LayoutEffect: refSample2: ${refSample2.current?.element}`)
        })
    
        console.log(`Before RefDemo Render return, refsample1 ${refSample1.current}`);
        console.log(`Before RefDemo Render return, refsample2 ${refSample2.current?.element}`);
        return (
            <>
            <div className="each-example">
                <h2>Check console, it will illustrate when ref will be populated and updated</h2>
                <p>For Functional Component, it will be updated after render and before Effect and Layout Effect</p>
                <div ref={refSample1}>
                    Hello I am Body  refSample1
                </div>
                <div>
                    <Button onClick={()=>setIsdiv(pre=>!pre)}>Click to Switch between div and span</Button>
                </div>
                <p>Bellow is refSample2</p>
                <RefFC ref ={refSample2} isdiv={isdiv}/>
                <p>
                    In Conslusion, for function component ref, is populated or updated after function return, but before Effect and layoutEffect.
                </p>
            </div>
            </>
        );
    }
    

    Let's talk about the React.forwardRef<RefProps,Props>() and React.ForwardRefRenderFunction<RefProps,Props> type

    lange is cheap, let's see the code. See, React.ForwardRefRenderFunction is the parameter type of forwardRef funciton.

    function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
    
  • 相关阅读:
    .NET开发微信公众号之创建自定义菜单
    FOR XML PATH 可以将查询结果根据行输出成XML格式
    Node入门
    javascript客户端检测技术
    理解OAuth 2.0(转)
    RESTful API 设计指南(转)
    forever让nodejs应用后台执行
    Git使用教程
    NodeJS基础教程
    windows系统下简单nodejs安装及环境配置
  • 原文地址:https://www.cnblogs.com/kongshu-612/p/14840898.html
Copyright © 2011-2022 走看看