1

I am working on a React project which is fetching data from Prismic headless CMS. Fetching data is an async function.

In HTML template I'm checking if data is fetched before rendering it with basic ternary operator ( { data ? (render data) : (no data fetched) } )

So in HTML, I want to set up some React DOM references. These references are needed in order to add animation elements later on.

My problem is that first I get null from reference (default value) and then I get useful reference value once data is fetched.

How could I stop the function that handles the state for animation from running until data is fetched?

Thanks.

Skafec
  • 49
  • 6

1 Answers1

1

React components do not know if a ref changes. So useEffect or componentDidUpdate don't help (you obviously know that).

But react knows if some content changes, so useEffect / componentDidUpdate get triggered if your element becomes available.

What you can do is to check on every update if your element is available, and (if you need it) store the availability in an own state.

Example:

export const DynamicRef = (props)=>{
    const [ value, setValue ] = useState('');
    const [ available, setAvailable ] = useState(false); // <-- store availability status
    const myRef = useRef();

    // -- create / remove element dynamically (you have your own logic here)
    useEffect(()=>{
        const timeout = setTimeout( ()=>{ setValue( !value ? 'hello, world!' : '' ); }, 1000 );
        return ()=>{ clearTimeout( timeout ); }
    }, [ value ])

    // -- check availability on EVERY update
    useEffect(()=>{
        if( !available && myRef.current ){
            setAvailable( true );

        } else if( available && !myRef.current ){
            setAvailable( false );
        }
    })

    // -- check ref
    console.log('ref:', myRef.current ? 'available' : 'not available', myRef);

    // --
    return <div>
        { value && <div ref={ myRef }>{ value }</div>}
    </div>
};
kca
  • 4,856
  • 1
  • 20
  • 41
  • Hello, thank you for your response. I actually decided to use the Promise inside the component to wait for the async function and once the function returns something, Promise can proceed to set up DOM references. – Skafec Jan 19 '21 at 11:23
  • Ok. Is it a workaround or a solid solution for this question ? If it is solid, It would be great to have it here as an answer. You may accept your own answer as well, that's ok in stackoverflow. – kca Jan 19 '21 at 15:30