#react

TILSeptember 05, 2019by Alexander Ivlev

Redux async actions. Tracking loading and errors with React hooks.

If you use redux and async actions, then you probably had to deal with a situation where you need to monitor the loading and error status of this action. With the advent of hooks, it became possible to conveniently transfer this logic to one block and use it everywhere.


import { useState, useCallback } from 'react';

import { useDispatch } from 'react-redux';



function useAsyncAction(action, dependeces = []) {

  const dispatch = useDispatch();

  const [loading, setLoading] = useState(false);

  const [isError, setIsError] = useState(false);



  const asyncAction = useCallback(

    (...args) => {

      async function callback() {

        setLoading(true);

        try {

          const res = await dispatch(action(...args));

          setIsError(false);

          setLoading(false);

          return res;

        } catch (e) {

          setLoading(false);

          setIsError(true);

          return e;

        }

      }

      callback();

    },

    [action, ...dependeces],

  );



  return [asyncAction, loading, isError];

}

Now you can use this hook in your functional component.


// …

  const [load, loading, isError] = useAsyncAction(() => loadActivityRequest(applicationId), [applicationId]);

// …

  load();

TILAugust 02, 2019by Maxim Romanov

How to blur a screen in React Navigation

Screens overlap each other in stackNavigator. React Navigation provides us not only with changing the background color of these screens, but also controlling their transparency.

To make the screen background blur, we first need to make the screens transparent.


import { createStackNavigator } from 'react-navigation';



export default createStackNavigator(

  {

    HomeStack,

    BlurModal,

  },

  {

    ...NAVIGATOR_CONFIG,

    mode: 'modal',

    cardStyle: { opacity: 1 },

    transparentCard: true,

  },

);

And then use blurView as background.


import React from 'react';

import { BlurView } from '@react-native-community/blur';

import Styled from 'styled-components';



function BlurModal() {

  return (

    <BlurWrapper blurType="light" blurAmount={20}>

      <Text>Modal with blur background</Text>

    </BlurWrapper>

  );

}



const BlurWrapper = Styled(BlurView)`

  position: absolute;

  top: 0;

  left: 0;

  bottom: 0;

  right: 0;

`;

TILJuly 17, 2019by Maxim Romanov

How to handle 401 unauthorized error in a Redux React application

In response to a client request, the server may return a 401 Unauthorized error. You must correctly catch it, for example, clear the state and redirect to the authorization page. To solve this problem, we wrote a custom Middleware which, in our opinion, is the best solution.


import * as actions from 'actions';



const authInterceptor = ({ dispatch }) => (next) => (action) => {

  if (action.status === 401) {

    dispatch(actions.removeJwt());

  } else {

    next(action);

  }

};

TILFebruary 20, 2019by Alexander Blinov

Custom onChange in React Final Form

Let's take a case when we need to call our own function to change a state of a specific field in a form (our react final form).

Here is a way to do the exact that:

You should pass your function as a parameter and after that just call it inside of the onChange method

Example:


const FormGroupAdapter = ({ input, inputOnChange }) => {

    const inputProps = {

        ...input,

        onChange: e => {

            input.onChange(e);

            inputOnChange && inputOnChange(e);

        }

    };



    return <input {...inputProps} />;

};



const handleChange = event => {

    console.log("!!!", event.target.value);

};



const App = () => (

    <Form

        ...

        render={({ handleSubmit, reset, submitting, pristine, values }) => (

            <form onSubmit={handleSubmit}>

                <div>

                    <label>some label</label>

                    <Field

                        name="someField"

                        component={FormGroupAdapter}

                        inputOnChange={handleChange}

                    />

                </div>

                ...

            </form>

        )}

    />

);



Live example

TILJanuary 24, 2019by Alexander Blinov

Reset values in React Final Form w/ keepDirtyOnReinitialize

How to reset values with keepDirtyOnReinitialize in React Final Form after submitting.

The Issue

If keepDirtyOnReinitialize is applied to your form, then form.reset() no longer able to remove field's value.

The Solution

The Solution is simple— if the form submitted successfully: first change keepDirtyOnReinitialize to false -> perform form reset form.reset() -> and change keepDirtyOnReinitialize back to true.


<Form

  onSubmit={onSubmit}

  keepDirtyOnReinitialize

  render={({ handleSubmit, form }) => (

    <form

       onSubmit={(event) => {

       const promise = handleSubmit(event);

       promise && promise.then(() => {

         form.setConfig('keepDirtyOnReinitialize', false);

         form.reset();

         form.setConfig('keepDirtyOnReinitialize', true);

       })

      return promise;

      }}

    >

    ...

   </form>

}/>

TILJanuary 22, 2019by Alexander Blinov

Reset values in React Final Form

How to reset values in React Final Form after submitting

At first I wrote the following code:


<Form

  onSubmit={onSubmit}

  render={({ handleSubmit, form }) => (

    <form

      onSubmit={event => {

        handleSubmit(event).then(() => {

          form.reset();

        })

      }}

    >

    ...

    </form>

  }/>

If we implement a function like this, we will get an error "Uncaught TypeError: Cannot read property 'then' of undefined”, when we try to submit invalid form.

Invalid forms — form with validation errors.

The solution

To avoid this error, we need to place handleSubmit(event) to a variable, and if the variable is not undefined call .then().


onSubmit={(event) => {

  const promise = handleSubmit(event);

  promise && promise.then(() => {

    form.reset();

  })

  return promise;

}}