Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Oct 13, 2025. It is now read-only.

unosquare/uno-react

Open more actions menu

Repository files navigation

npm version Build Status

uno-react

⭐ Please star this project if you find it useful!

Common functions, HOCs and hooks for React.

Table of contents

Installation

> npm i uno-react

We are using hooks, so you need to work with React ^16.8.0.

What's in the library

In this section, we present the different components that are available in the uno-react library. Please keep in mind that everything in the library is opt-in. uno-react is completely opt-in. It won't force you to use any of its components, classes or methods.

Hooks

useClickOutside

This hook allows to call a given function when a click event occurs outside the component.

Parameters

  • component functionComponent The component to be wrapped.
  • callback function The function that will be called when the click event occurs outside the component.

Example

const myComponent = () => {

    const [color, setColor] = React.useState('green');
    const onClick = () => setColor('green');

    const toBeEnhanced = () => (
        <div
            style={{ backgroundColor: color }}
            onClick={onClick}
        />
    );

    const functionToApply = () => setColor('red');
    const Enhanced = useClickOutside(toBeEnhanced, functionToApply);

    return (
        <div
            style={{
                height: '80px',
                width: '80px',
            }}
        >
            <Enhanced />
        </div>
    );
};

useEffectWithDebounce

This hooks run an effect with a debounce. Each time any input change, it will be registered; when happens the debounce time whitout changes, the effect will be run. (This function does not return anything).

Parameters

Example

    const MyComponent = () => {
     const [searchText, handleChange, setSearchText] = useStateForField('');
     const debounceTime = 2000; // 2 Seconds
     const searchUsers = () => console.log(`searching: ${searchText}`);

     useEffectWithDebounce(searchUsers, debounceTime, [searchText]);

     return (
         <>
             <h1>Input: </h1>
             <input
                 value={searchText}
                 onChange={handleChange}
             />
             <p> Open the console </p>
         </>
     );
    };

useEffectWithLoading

This hook handles the process of getting a external resource like a fetch or reading a file, and prevent updating the react state if the component is unmounted before the resource is loaded.

Parameters

note: The effect function that is given as a parameter will be run when the component has been mounted and when any inputs item change.

Returns [getter, isLoading]

  • getter: Object the value that is returned by the effect function when the data has been loaded, otherwise the initialValue.
  • isLoading: boolean a flag that indicates if the data has been fetched or not.

Example

const myComponent = ({ myId }) => {
    const myDefault = '';
    const inputs = [];
    const [ myData, isLoading ] = useEffectWithLoading(getMyData(myId), myDefault, inputs);
   
   return (
        <div>
            {isLoading ?
                <div class='loader'>Loading ...</div>
                :
                <form>
                    <label>
                        <h1>Data loaded</h1>
                        {myData}
                    </label>
                <form>}
        </div>
    );
};

useNow

This hook keep the current Date object updated. The value will be updated each second.

note: the time value is a javascript Date instance, you can manipulate it as any other javascript Date object.

Returns [now]

  • now: Date the current date.

Example

const myComponent = () => {
    const [now] = useNow();
    
    return (
        <div>
            Seconds: {now.getSeconds()}
        </div>
    );
};

usePersistedState

This hook allows us to set and get values from the localStorage.

Parameters

  • defaultValue string the default values, this value will be added to the localStorage and returned if the key is not found.

  • keyName string the key-id to save the value on the localStorage.

note: the defaultValue just will be setted and returned if the keyName is not on the localStorage, otherwise the value found will be returned.

Returns [getter, setter]

Example

const myComponent = () => {
    const key = 'exampleToken';
    const defaultValue = 'unosquareToken';
    const [token, setToken] = usePersistedState(defaultValue, key);

    const changeValue = () => setToken('1928238475');

    return(
        <div>
            <h1>{token}</h1>
            <button onClick={changeValue}>Change value</button>
        </div>
    );
};

useResolutionSwitch

This hook listen to the resize window event and keep the isResolution flag updated.

Parameters

  • outerWidth number Size limit (px). defaultValue: 1000

  • timeout number Debounder timeout, the variable will change after this debounder time (ms). defaultValue: 500

Returns [size]

  • size: boolean true when window outerSize is smaller than the outerWith passed as a parameter.

Example

    const myComponent = () => {
        const outerWidth = 500;
        const timeout = 1000;
        const [size] = useResolutionSwitch(outerWidth, timeout);
        
        return (<h1>{size ? 'mobile' : 'desktop'}</h1>);
    };

useStateForField

Similar to useStateForModel this hook helps us to keep the value of a variable that is related to an input, but in this case useStateForField works just with one value.

Parameters

  • initialValue Object initial value or initial model.

Note: In contrast with useStateForModel in this hook the function handleChange can not be called with an object as a param, to handle a change manually we have the setField function.

Returns [getField, handleChange, setField]

  • getField: Object the current value, that keeps the information updated.
  • handleChange: Function this function should be called on the onChange event.
  • setField: Function this function helps us to update the value manually.

Example

const myComponent = () => {
    const [ myValue, handleChange, setMyValue ] = useStateForField('Unosquare');
    
    const reset = () => setMyValue('Unosquare');
    
    return (
        <div>
            <h1>{myValue}</h1>
            <input
                value={myValue}
                onChange={handleChange}
            />
            <button onClick={reset}>Reset value</button>
        </div>
    );
};

useStateForModel

This hook allows us to keep updated the values of a model that are related to an input, handling the input's onChange calls. During the first render the model will have the initialValue.

Parameters

  • initialValue Object initial value or initial model.

Note: the handleChange method will update the model by the target.name event property if it is found, otherwise it will be added to the model.

Note: calling the handleChange method with an object as a param instead of an event, the object will be merged with the current model.

Returns [model, handleChange]

  • model: Object the current model, that keeps the information updated.
  • handleChange: Function this function should be called on the onChange event.

Example

const myComponent = () => {
    const [ model, handleChange ] = useStateForModel({
        id: 1,
        name: 'Mario',
        lastName: 'Di Vece',
    });

    const changeName = () => handleChange({name: 'Mario'});

    return (
        <div>
            <h1>{model.id} - {model.name} - {model.lastName}</h1>
            <input 
                name="name"
                onChange={handleChange} 
                value={model.name}
            />
            <input 
                name="lastName"
                onChange={handleChange}
                value={model.lastName}
            />
            <button onClick={changeName}>Reset Name</button>
        </div>
    );
};

useStateForModelWithLoading

This hook allows us to keep updated the values of a model that are related to an input, handling the input's onChange calls like useStateForModel does, but in additino this hook allows us to load the data from an external resource.

This hook is a mix between useStateForModel and useEffectWithLoading, you can use it just as useStateForModel and handle the loading with the extra variable returned isLoading.

Parameters

note: The effect function that is given as a parameter will be run when the component has been mounted and when any inputs item change.

Returns [getter, isLoading, handleChange]

  • getter: Object the value that is returned by the effect function when the data has been loaded, otherwise the initialValue.
  • isLoading: boolean a flag that indicates if the data has been fetched or not.
  • handleChange: Function this function should be called on the onChange event.

Example

const myComponent = () => {
    const myModel = {
        name: 'my test name',
        city: 'my test city'
    };
    const [mySearchString, handleChangeSearchString] = useStateForField('');
    const [ data, isLoading, handleChange ] = useStateForModelWithLoading(getMyData(mySearchString), myModel, [mySearchString]);
    
    return (
        <div>
            <input 
                onChange={handleChangeSearchString} 
                value={mySearchString}>
            </input>
            {isLoading ?
                <div class='loader'>Loading ...</div>
                :
                <form>
                    <input
                        value={data.name}
                        onChange={handleChange}
                    />
                    <input
                        value={data.city}
                        onChange={handleChange}
                    />
                </form>}
        </div>
    );
};

useToggle

This hook handles the switch on boolean values. The value will be toggled each time the function toggle is called.

Parameters

  • defaultValue boolean default or initial value.

Returns [getField, toggleField]

  • getField: boolean the current value.
  • toggleField: Function the function that toggles the value.

Example

const myComponent = () => {
    const defaultValue = false;
    const [ myValue, toggle ] = useToggleStateForField(defaultValue);
    
    return (
        <div>
            <h1> {myValue ? 'true' : 'false'}</h1 >
            <button
                onClick={toggle}
            >
                Toggle
            </button>
        </div >
    );
};

HOCs

enhanceWithClickOutside

This HOC allows to the wrapped component to call a function when a click event occurs outside the component. The function that will be call must be named handleClickOutside and should receive an event as parameter.

Example

class ToBeEnhanced extends React.Component<any> {

    constructor(props) {
        super(props);
    }

    public render() {

        return (
            <div
                style={{
                    backgroundColor: 'red',
                    height: '100px',
                    width: '100px',
                }}
            />
        );
    }

    private handleClickOutside = (e) => {
        //Do what you want in here.
    }
}

const Enhanced = enhanceWithClickOutside(ToBeEnhanced);

const Test = () => {

 return (
  <Enhanced />
 );
};

Functions

asyncOnEnterKey

This function is similar to onEnterKey, the only difference is that the callback should be an async function.

Parameters

  • callback function The function that will be called when the "enter" key is pressed.

Example

const myComponent = () => {
 
 const onEnter = async() => await asynFunction();
 
 return(
  <div onKeyDown=(asyncOnEnterKey(onEnter))>   
  <div/>
 );
};


const SearchBox: React.FunctionComponent<any> = ({retrieveInput}) => {
    const [search, changeSearch] = useStateForField('');
   
    const action = async() => await retrieveInput(search);
    
    return (
        <TextField
            onKeyDown={asyncOnEnterKey(action)}
            value={search}
            onChange={changeSearch}
        />
    );
};

colorGenerator

This function retrieves an Array of RGB colors that are a result of an interpolation between to given RGB colors.

Parameters

  • startColor Array RGB color (<Red|Green|Value>) that represents the start color for the interpolation.
  • endColor Array RGB color (<Red|Green|Value>) that represents the end color for the interpolation.
  • factor Number The ratio of the output rate to the input rate(startColor -> endColor).

Returns

  • Colors Array RGB colors array.

Example

const myComponent = () => {
    const startColor = [255, 0, 0];
    const endColor = [0, 255, 0];

    const colors = ColorGenerator(startColor, endColor, 1); //Array of colors result of the interpolation.

    //Here we use the array of colors to create new divs using the color data to set the backgroundColor value.
    //Every color represents a RGB array (color[0] = red channel value, color[1] = green channel value, color[2] = blue channel value)
    return (
        <div
            style={{
                height: 'auto',
                width: '100px',
            }}
        >
            {
                colors.map((color, index) => (
                    <div
                        key={index}
                        style={{
                            backgroundColor: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
                            height: '10px',
                            width: '10px',
                        }}
                    />
                ))
            }
        </div>
    );
};

createFetchController

This function works as a "quick start" for requestController, this function allows you to use a default headersResolver and a default responseSolver.

Parameters

Returns

Example

const requestController = createFetchController({});
const response = await requestController('http://testUrl', null, 'Get', null);

debounce

This function allow to apply a function after certain amount of time.

Parameters

  • F function A function to be executed.
  • waitMilliseconds number The number of miliseconds to wait before execute the function.

Example

const SearchBox: React.FunctionComponent<any> = ({retrieveInput}) => {
    const [search, changeSearch] = useStateForField('');
  
    const action = () => retrieveInput(search);
    const onChange = (ev) => debounce(()=> changeSearch(ev.target.value), 500);
 
    return (
        <TextField
            onKeyDown={onEnterKey(action)}
            value={search}
            onChange={onChange}
        />
    );
};

humanize

This function takes a string and converts in to a more "readable" string.

Parameters

  • name String A string that will be humanized.

Returns

  • humanized String The new string.

Example

const humanized = humanize("StringThatWillBeHumanized"); //"String That Will Be Humanized" 

onEnterKey

This function is a HOF that takes a function as parameter which will be call when the "enter" key is pressed, this HOF should be used as a component's prop that will be involved in keyboard events.

Parameters

  • callback function The function that will be called when the "enter" key is pressed.

Example

const SearchBox: React.FunctionComponent<any> = ({retrieveInput}) => {
    const [search, changeSearch] = useStateForField('');

    const action = () => retrieveInput(search);

    return (
        <TextField
            onKeyDown={onEnterKey(action)}
            value={search}
            onChange={changeSearch}
        />
    );
};

toTitleCase

This function takes a string and converts it to "Title Case", that means, it uses each word (separated by a space) and capitalizes the first letter of each word.

Parameters

  • title String A string that will be transform to title case.

Returns

  • title String The new string.

Example

const newTitle = toTitleCase("title test"); // "Title Test"

ValidatorForm

This component extends the original ValidatorForm rules. This component works for wrap TextValidator component(s) and for register any other custom rules, this rules can be used in the wrapped components.

Rules:

  • isNotAllBlanks: Validates that the input is not empty, white spaces are ignored.
  • maxNaturalNumber: Validates that the input number si not greather than the given.
  • validateEndDate: Validates than endDate is later than startDate.
  • startDateGreaterThanEndDate: Validates that a date is bigger than other.
  • isImage: Verify that the input correspond to a image name with image file extension.
  • atLeastOneLowerAndUpperCase: Verify that the input has at least one letter in lower case and one in upper case.
  • atLeastOneNumber: Verify that the input has at least one number.
  • atLeastOneSpecialCharacter: Verify that the input has at least one special character (e.g. * # $ &).
  • pincodeValidator: Verify the input contains only numeric values and has a length of 6 characters.
  • password: Validated that the input has at least a length of 8 characteres and contains especial characters, lower case & upper case characters.
  • isPasswordMatch: Verify that the input is equal to another value.(e.g. when validated password & password verfication fields).

Example

const form = () => {
    const [fields, handleChange] = useStateForModel({
        atLeastOneLowerAndUpperCase: '',
        atLeastOneNumber: '',
        atLeastOneSpecialCharacter: '',
        isImage: '',
        isNotAllBlanks: '',
        isPasswordMatch: '',
        maxNaturalNumber: '',
        password: '',
        pincodeValidator: '',
        startDateGreaterThanEndDate: '',
        validateEndDate: '',
    });

    return (
        <ValidatorForm
            autoComplete='off'
            instantValidate={true}
        >
            <TextValidator
                id='isNotAllBlanks'
                value={fields.isNotAllBlanks}
                onChange={handleChange}
                validators={['required', 'isNotAllBlanks:5']}
                errorMessages={[
                    'This field is required',
                    'The minimum length is 5 characters, blank spaces are ignored',
                ]}
            />
            <TextValidator
                id='maxNaturalNumber'
                value={fields.maxNaturalNumber}
                onChange={handleChange}
                validators={['required', 'maxNaturalNumber:100']}
                errorMessages={[
                    'This field is required',
                    'The input should not be greater than 100',
                ]}
            />
            <TextValidator
                id='validateEndDate'
                value={fields.validateEndDate}
                onChange={handleChange}
                validators={['required', 'validateEndDate: 2019:07:29']}
                errorMessages={[
                    'This field is required',
                    'The date should be earlier than 2019:07:29',
                ]}
            />
            <TextValidator
                id='startDateGreaterThanEndDate'
                value={fields.startDateGreaterThanEndDate}
                onChange={handleChange}
                validators={['required', 'startDateGreaterThanEndDate: 2019:07:29']}
                errorMessages={[
                    'This field is required',
                    'The start date should be greater than 2019:07:29',
                ]}
            />
            <TextValidator
                id='isImage'
                value={fields.isImage}
                onChange={handleChange}
                validators={['required', 'isImage: .jpg']}
                errorMessages={[
                    'This field is required',
                    'The file extension should be .jpg',
                ]}
            />
            <TextValidator
                id='atLeastOneLowerAndUpperCase'
                value={fields.atLeastOneLowerAndUpperCase}
                onChange={handleChange}
                validators={['required', 'atLeastOneLowerAndUpperCase']}
                errorMessages={[
                    'This field is required',
                    'Should have at least one upper case and one lower case character',
                ]}
            />
            <TextValidator
                id='atLeastOneNumber'
                value={fields.atLeastOneNumber}
                onChange={handleChange}
                validators={['required', 'atLeastOneNumber']}
                errorMessages={[
                    'This field is required',
                    'Should contain at least one number',
                ]}
            />
            <TextValidator
                id='atLeastOneSpecialCharacter'
                value={fields.atLeastOneSpecialCharacter}
                onChange={handleChange}
                validators={['required', 'atLeastOneSpecialCharacter']}
                errorMessages={[
                    'This field is required',
                    'Should contain at least one special character',
                ]}
            />
            <TextValidator
                id='pincodeValidator'
                value={fields.pincodeValidator}
                onChange={handleChange}
                validators={['required', 'pincodeValidator']}
                errorMessages={[
                    'This field is required',
                    'should not contain white spaces and a length of 6 characters',
                ]}
            />
            <TextValidator
                id='password'
                value={fields.password}
                onChange={handleChange}
                validators={['required', 'password']}
                errorMessages={[
                    'This field is required',
                    'Should have at least 1 upper case, 1 lower case, 1 special character and a min length of 8 characters',
                ]}
            />
            <TextValidator
                id='isPasswordMatch'
                value={fields.isPasswordMatch}
                onChange={handleChange}
                validators={['required', `isPasswordMatch:${fields.Password}`]}
                errorMessages={[
                    'This field is required',
                    'Must be the same as the password field',
                ]}
            />
        </ValidatorForm>
    );
};

Packages

No packages published

Contributors 12

Morty Proxy This is a proxified and sanitized view of the page, visit original site.