SyntaxStudy
Sign Up
React Synchronising with External Systems
React Beginner 1 min read

Synchronising with External Systems

Some effects connect a React component to something that lives entirely outside React — a chat service, an analytics library, or a third-party map widget. The useEffect hook is designed for exactly this: you imperatively set up the connection on mount and tear it down on cleanup, while React state flows the latest props into the external system whenever they change. A common mistake is writing effects that update state based on other state, creating a chain of effects that is hard to trace. If you only need to derive a value, compute it directly during render; effects should be reserved for synchronisation with something outside React, not for in-React data transformations. When you find yourself writing many effects that coordinate with each other, consider extracting them into a custom hook. Custom hooks group related effect logic, expose only the minimal return value, and make components leaner and easier to read.
Example
import { useEffect, useRef } from 'react';

// Imaginary third-party map library
// const map = new ThirdPartyMap(container, { zoom, center });

function MapWidget({ zoom, center }) {
    const containerRef = useRef(null);
    const mapRef = useRef(null);

    // Create the map once on mount
    useEffect(() => {
        mapRef.current = new window.ThirdPartyMap(containerRef.current, {
            zoom,
            center,
        });

        return () => {
            mapRef.current.destroy(); // cleanup
            mapRef.current = null;
        };
    }, []); // eslint-disable-line react-hooks/exhaustive-deps

    // Synchronise zoom whenever it changes
    useEffect(() => {
        if (mapRef.current) {
            mapRef.current.setZoom(zoom);
        }
    }, [zoom]);

    // Synchronise center whenever it changes
    useEffect(() => {
        if (mapRef.current) {
            mapRef.current.setCenter(center);
        }
    }, [center]);

    return <div ref={containerRef} style={{ width: '100%', height: 400 }} />;
}