SPFx – Using Custom Hooks

Introduction

In this post, let us see how we can use Custom Hooks in SharePoint Framework.

What is Hooks?

Hooks are a special function introduced in React 16.8. They let us use state and other react features isolated from other components without writing a class. They provide a simple way of creating a reusable function. They also allow us to reuse the stateful logic without changing the component hierarchy. There are some of the inbuilt hooks like useState, useEffect etc. You can see this link for the list of inbuilt hooks.

Let us start by creating a new web part project using yeoman SharePoint generator, before that create a folder where you want to create the web part. Navigate to that folder and run the below command

yo @microsoft/sharepoint

The generator will asks you couple of questions,

  • Enter the webpart name as your solution name, and then select Enter.
  • Select Create a subfolder with solution name for where to place the files.
  • Select Y to allow the solution to be deployed to all sites immediately.
  • Select N on the question if solution contains unique permissions.
  • Enter the webpart name
  • Enter the webpart description
  • Choose the framework as ‘React

Open the code in VSCode which is my favorite and flexible code editor for SharePoint Framework. You can directly open the project folder from the file menu or use the below command to open the VSCode from command line.

cd \web part folder\
code .

Before diving into the code, there are some rules that we should be aware while creating or using hooks.

  • Only call Hooks at the top level, do not use it inside the loops.
  • Only call Hooks from React functions. You can call Hooks from React functional components or within the custom Hooks.
  • Custom Hook should always starts with use keyword inorder for the react to identify that it is a hook and then to apply all the validation rules related to the hook.

We have to make sure the above rules are met. So the first step is to make the default class component into functional component. Navigate to your <webpart>.tsx file. Copy-paste the below code to change it to the functional component.

import * as React from 'react';
import styles from './CustomHooks.module.scss';
import { SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
import { useLoader } from './loaderHook';
import { useIndicator } from './indicatorHook';

const CustomHooks: React.FunctionComponent<{}> = (props) => {
    return (
        <>
            <div className={styles.customHooks}>
                <div className={styles.container}>
                    <div className={styles.row}>
                        {useLoader("Loader using custom hooks", SpinnerSize.large, 'bottom')}
                        {useIndicator('Please wait...', 'Loading the data')}
                    </div>
                </div>
            </div>            
        </>
    );
};

export default CustomHooks;

The above code use to custom Hooks called useLoader and useIndicator. The two Hooks are very simple which just load the Spinner and ProgressIndicator from Office UI Fabric component.

Create a new file called loaderHook.tsx within the component folder. Copy-paste the below code.

import * as React from 'react';
import { IStackProps, Stack } from 'office-ui-fabric-react/lib/Stack';
import { Spinner, SpinnerSize, SpinnerLabelPosition } from 'office-ui-fabric-react/lib/Spinner';

const rowProps: IStackProps = { horizontal: true, verticalAlign: 'center' };
const tokens = {
    sectionStack: {
        childrenGap: 10,
    },
    spinnerStack: {
        childrenGap: 10,
    },
};
export function useLoader(content: string, spinSize: SpinnerSize, labelPosition?: SpinnerLabelPosition) {
    return (
        <Stack tokens={tokens.sectionStack}>
            <Stack {...rowProps} tokens={tokens.spinnerStack}>
                <Spinner label={content} size={spinSize} labelPosition={labelPosition ? labelPosition : 'top'} />
            </Stack>
        </Stack>
    );
}

The above is just a function which gets 3 properties

  • content – The message to be displayed as a label
  • spinSize – The size of the spinner to be used.
  • labelPosition – The position of the label which is optional, default will be at the top.

Create a new file called indicatorHook.tsx within the component folder. Copy-paste the below code.

import * as React from 'react';
import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';

export function useIndicator(label: string, description: string) {
    return (
        <>
            <ProgressIndicator label={label} description={description} />
        </>
    );
}

The above custom hook takes 2 properties

  • label – The text to be displayed at the top
  • description – The text to be displayed at the bottom

Thats it, you are done with the code changes. Now run the gulp serve to see how it works.

Preview

Source Code

The source code along with other samples can be found in the below github link.

SPFx-Demos

Happy Coding…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s