Categories
Programming React User Interface

React – UseLocationState hook

This hook, made in typescript, can be used to change the current location state. Just use it as you would use the useState hook.

import { useHistory } from "react-router-dom";
import { useCallback } from "react";

//callback definition.
type SetStateType<T> = ((prevState: T) => T) | T;

export default <T extends any>(defaultState: T)
    : [T, (newState: SetStateType<T>) => void] => {

    const { replace, location: { state } } = useHistory<T>(); 
    const currentState = isNullOrUndefined(state) ? defaultState : state;

    const setState = useCallback((newState: SetStateType<T>) => {
        const state = (newState instanceof Function)
            ? newState(currentState)
            : newState;
        state !== currentState && replace({ state });
    }, [replace, currentState]);

 return [currentState, setState];
}

UPDATE Jan 2022: Simplified version using useState():

import { useHistory } from "react-router-dom";
import { useEffect, useState } from "react";

//callback definition.
type SetStateType<T> = ((prevState: T) => T) | T;

const useLocationState = <T extends any>(defaultState: T)
    : [T, (newState: SetStateType<T>) => void] => {

    const { replace, location } = useHistory<T>();
    const [state, setState] = useState<T>(location.state || defaultState);

    //save state in locationState
    useEffect(() => {
        location.state !== state && replace({ state });        
    }, [replace, state, location.state])

    return [state, setState];
}

export default useLocationState;

Example:

import * as React from 'react';
import useLocationState from '../UseLocationState';

export default (() => {
    const [someState, setSomeState] = useLocationState({ test: 1 });

    //change location state (2 options)
    useEffect(() => {
        //option 1
        setSomeState({ test: 10 });
        //option 2
        setSomeState(prev => ({ test: prev.test - 5 })) ;
    }, [setSomeState]);

    return <>{someState}</>
}

Categories
Services

Environment Variables in Net Core 3 with React and Docker

This code replaces React Environment Variables with docker variables at runtime (first run only!). This makes it possible to present different environment vars at startup instead of at build time. This is especially useful when using docker containers. You can make one docker image for different environments.

Development mode : You can still use .env files (as described in react documentation). Nothing changed here.

Production or other build modes: The react environment vars will be replaced in the static html file at startup.

This approach has as advantage that you do not need to inject vars on every single page request (dynamic content). This solution changes the variables only once on startup and keeps the file static throughout the program runtime. This also means that this code cannot be used for variables that changes between requests.

Categories
User Interface

React Prompt on page unload (Typescript)

This React Prompt Component allows you to show a dialog before closing a page or when navigating to another page. This is an extension on the existing prompt component within React which only shows dialog messages when navigating with React Router. This component works in hooks and class components.

Copy paste the code below and save it as DirtyPrompt.tsx