Skip to content

Refactoring React

State that depends first on props and then on useEffect

GET /dashboard/<ID> will get a JSON response

{
    "dashboard": {
        "id": 9,
        "name": "Dashboard name",
        ...
}

GET /dashboard will get the same JSON response

const DashboardRenderer = ({ urlId }) => {
// init
const [backendId, setBackendId] = useState(urlid);
const dashboard = useSelector({dashboards} => dashboards[backendId]);

const dispatch = useDispatch();
useEffect(() => {
        loadDashboard(dispatch, backendId).then(({ data }) => {
            setBackendId(data.id);
        });
    });
}, [dispatch, backendId]);
  1. First render: urlId is null
  2. useEffect is called
    1. It sets the backendId state which triggers a re-render
  3. Second re-render: runs the useEffect again
    1. makes another API call

How to only make one API call?

Solution: only use the prop in the useEffect

const DashboardRenderer = ({ urlId }) => {
// init
const [backendId, setBackendId] = useState(urlId);
const dashboard = useSelector({dashboards} => dashboards[backendId]);

const dispatch = useDispatch();
useEffect(() => {
-       loadDashboard(dispatch, backendId).then(({ data }) => {
+       loadDashboard(dispatch, urlId).then(({ data }) => { 
            setBackendId(data.id);
        });
    });
- }, [dispatch, backendId]);
+ }, [dispatch, urlId]);

Last update: 2022-09-23