0.0.11 • Published 2 years ago

twa-client-sdk-react v0.0.11

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

SDK React

Ecosystem Component NPM Size License

React bindings for client SDK. Contains hooks, components and other useful tools which allow usage of React along with Web Apps client SDK. Tracks SDK components changes out of box.

To learn how client SDK works, please, refer to its official documentation.

Installation

Before everything, it is assumed, that you already installed react package as long as this plugin has it as peer dependency. Installation of SDK itself is not required, current package already includes it.

Then, you can install this package via this command:

npm i twa-client-sdk-react

or

yarn add twa-client-sdk-react

Usage

Initializing

According to SDK documentation, it represents a set of components, which are not initialized by default and developer should create them by himself. Additionally, SDK provides function called init which allows developers not to think about "how do I even should create these components?" and creates components by itself.

So, as you could think, the first thing we have to do is to provide application SDK functionality and allow it calling initialization to get newly created components. For this purpose, component SDKProvider exist:

import React from 'react';
import {SDKProvider} from 'twa-client-sdk-react';

function Root() {
  return (
    <SDKProvider>
      <div>My application!</div>
    </SDKProvider>
  );
}

Insertion of this component allows its child elements to use hook useSDK returning core SDK information:

import React from 'react';
import {SDKProvider, useSDK} from 'twa-client-sdk-react';

function App() {
  const sdk = useSDK();

  // Here, we can use SDK information.

  return <div>My application!</div>;
}

function Root() {
  return (
    <SDKProvider>
      <App/>
    </SDKProvider>
  );
}

Ok, we have access to SDK now, but what about init function? We don't have to call this function as long as SDKProvider will do it for us when it was attached to DOM. Let's complicate previous example and add important logic connected with SDK lifecycle:

import React, {PropsWithChildren, useEffect} from 'react';
import {SDKProvider, useSDK, useBackButton, useWebApp} from 'twa-client-sdk-react';

/**
 * Part of application which is free of using SDK components.
 */
function App() {
  const backButton = useBackButton();
  const webApp = useWebApp();

  // When App is attached to DOM, lets show back button and
  // add click event handler, which will close application.
  useEffect(() => {
    backButton.on('click', webApp.close);
    backButton.show();

    return () => {
      backButton.off('click', webApp.close);
      backButton.hide();
    };
    // We know, that backButton and webApp will never change,
    // but let's follow React rules.
  }, [backButton, webApp]);

  return <div>My application!</div>;
}

/**
 * This component controls render of important part of application
 * which uses hooks, returning SDK components.
 */
function Loader({children}: PropsWithChildren) {
  const {didInit, components} = useSDK();

  // There were no calls of SDK's init function. It means, we did not
  // even try to do it.
  if (!didInit) {
    return <div>SDK init function is not yet called.</div>;
  }

  // If components is null, it means, SDK is not ready at the
  // moment and currently initializing. Usually, it takes like
  // several milliseconds or something like that, but we should
  // have this check.
  if (components === null) {
    return <div>Warming up SDK.</div>;
  }

  // Safely render application.
  return <>{children}</>;
}

/**
 * Root component of the whole project.
 */
export function Root() {
  return (
    <SDKProvider>
      <Loader>
        <App/>
      </Loader>
    </SDKProvider>
  );
}

You could probably ask why we should use component like Loader. The problem is, as long as SDK initialization is asynchronous (some of its components should send requests to native app), we could not determine which properties its components should have. That is the reason, why SDKProvider can not provide valid components property until initialization is completed.

As a result, all hooks which return component instances will throw an error as long as they could not get their component from components property. That is the reason, why these hooks should not be called until SDK is initialized.

When init is done

When initialization was completed successfully, do not forget to call webApp.ready function. This will notify native application about current Web App is ready to be displayed.

import {useWebApp} from 'twa-client-sdk-react';
import React, {useEffect} from 'react';

function App() {
  const webApp = useWebApp();

  useEffect(() => {
    webApp.ready();
  }, [webApp]);
  
  return <div>Here is my App</div>;
}

Hooks and HOCs

Theme

There are some cases, when it is required to use theme parameters information even when SDK is not ready yet. For example, you would probably want to know theme colors to render app loader with appropriate colors.

For this purpose, hook useThemeFromLocation is used:

import {useThemeFromLocation} from 'twa-client-sdk-react';
import React, {useEffect} from 'react';

function App() {
  const theme = useThemeFromLocation();

  return <div>Background color: {theme.backgroundColor}</div>;
}

Internally, this hook uses twa-theme-paramss package extractFromLocation function, which extracts theme information from current window location.

Other

Library provides list of dead simple hooks and HOCs for each SDK component. Returned instances are always the same, but force updates will be called in case, something changed in component.

WARNING: In case, you use HOCs, pay attention to the fact, passed components are always the same instances. This may lead to problems with PureComponents as long as they will not see any changes in references. Do not create new components instances as long as it will lead to new problems connected with events listening done during SDK initialization process.

Contribution

Any contribution is appreciated. Feel free to create new feature requests, bug reports etc.

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago