Fluent Commerce Logo
Docs
Sign In

React Hooks in the Component SDK

Essential knowledge

Author:

Fluent Commerce staff

Changed on:

27 June 2024

Overview

Component SDK provides a collection of React hooks to allow custom components to access the core UX framework functionality.

The SDK includes Typescript declaration files that tell your IDE and compiler what these look like and that they are available on the global scope.

Key points

  • Component SDK provides a collection of React hooks to allow custom components to access the core UX framework functionality.
  • The useAuth can access user session information.
  • The useEnv can access the current environment details.
  • The useI18n can access the global language to translate static labels
  • The useSetting / getSettings can access the current account setting values.
  • The useQuery/getQuery and useRest/getRest to retrieve data from OMS.
  • The useData hook provides direct access to the page query response and variables.

Hooks

Component SDK provides a collection of React hooks to allow custom components to access the core UX framework functionality.

The SDK includes Typescript declaration files that tell your IDE and compiler what these look like and that they are available on the global scope.

useAuth

User login session information, provides access to:

  • details of the logged in user
  • current roles and permissions
  • ability to switch contexts (i.e. between different retailers or locations the user has access to)
  • ability to log out
1// SampleUseAuth.tsx
2
3import { FC } from 'react';
4import { useAuth } from 'mystique/hooks/useAuth';
5
6export const SampleUseAuth: FC = () => {
7  const auth = useAuth();
8
9  const SimpleLayout = (heading: string, content: string) => {
10    return (
11      <div>
12        <h3>
13          <u>{heading}:</u>
14        </h3>
15        {content}
16        <br /> <br />
17      </div>
18    );
19  };
20
21  return (
22    <div>
23      <h1>useAuth Example</h1>
24      <h2>Examples of reteiving data from useAuth</h2>
25      {SimpleLayout('auth json:', JSON.stringify(auth))}
26
27      {SimpleLayout(
28        'JSON.stringify(auth.context)',
29        JSON.stringify(auth.context)
30      )}
31
32      {SimpleLayout(
33        'retailer Ref auth.context.current.details?.ref',
34        auth.context.current.details?.ref
35      )}
36
37      {SimpleLayout(
38        'username auth.context.current.details?.ref',
39        auth.user.username
40      )}
41    </div>
42  );
43};
44
45//add the following into index.tsx:
46import { SampleUseAuth } from './components/SampleUseAuth';
47
48ComponentRegistry.register(['SampleUseAuth'], SampleUseAuth, {
49  category: 'content',
50});
51

Language: tsx

Name: Examples of how to use useAuth()

Description:

a few examples on how to get data by using useAuth()

useEnv

Details of the current environment:

  • the Fluent Account name
  • the current Web App name (eg. "oms")
1// SampleUseAuth.tsx
2
3import { useEnv } from 'mystique/hooks/useEnv';
4import { FC } from 'react';
5
6export const SampleUseEnv: FC = () => {
7  const env = useEnv();
8
9  const SimpleLayout = (heading: string, content: string) => {
10    return (
11      <div>
12        <h3>
13          <u>{heading}:</u>
14        </h3>
15        {content}
16        <br /> <br />
17      </div>
18    );
19  };
20
21  return (
22    <div>
23      <h1>useAuth Example</h1>
24      <h2>Examples of reteiving data from useAuth</h2>
25      {SimpleLayout('JSON.stringify(env)', JSON.stringify(env))}
26
27      {SimpleLayout('env.app', env.app)}
28      {SimpleLayout('env.account', env.account)}
29      {SimpleLayout('env.api', env.api)}
30    </div>
31  );
32};
33
34
35//add the following into index.tsx:
36import { SampleUseEnv } from './components/SampleUseEnv';
37
38ComponentRegistry.register(['SampleUseEnv'], SampleUseEnv, {
39  category: 'content',
40});
41

Language: tsx

Name: Examples of how to use useEnv()

Description:

a few examples on how to get data by using useEnv()

useI18n

Automatically translate static labels, generally for things that aren't coming from manifest configuration (as those are automatically translated).

If the user changes languages during a session, these strings will automatically be re-translated and the component will re-render without requiring additional code.

For example, on an ID confirmation component:

1import { Card } from 'mystique/components/Card';
2import { useI18n } from 'mystique/hooks/useI18n';
3import { FC } from 'react';
4
5const ConfirmID: FC = () => {
6  const { translate } = useI18n();
7  return (
8    <Card>
9        <h2>{translate('acme.collection.customerConfirmMessage')}</h2>
10        <Button label={translate('acme.collection.customerConfirmButton')} />
11    </Card>
12  );
13}

Language: tsx

Name: an ID confirmation component

Description:

[Warning: empty required content area]

In some cases you might find yourself with several keys that might fit the label, or want to provide a default value in the code. The 

`translateOr`
 function allows several keys to be passed in, and will return either the value of the first language-file match, or the literal value of the last key (as a default).

1const ErrorDialogue: FC = () => {
2  const {translateOr} = useI18n();
3  return (
4    <span>{translateOr([
5        'acme.errors.specificErrorMessage',
6        'acme.errors.genericErrorMessage',
7        'There was a problem' // will be returned if no key above matches
8    ])}</span>
9  );
10}
11

Language: tsx

Name: Code sample

Description:

[Warning: empty required content area]

Finally, the useI18n hook provides information about the available and currently selected languages.

useSettings

Many components are configured at a retailer or account level using settings. The useSetting hook gives easy access to those values.

By default, 

`useSettings`
 will find the setting value at the current context the user is logged into. Depending on the web app manifest setup this could be a location or a retailer.

From there, it will cascade up the context hierarchy (location, to retailer, to account) until it finds a setting of the name provided and return the first (meaning most specific) match.

1const SettingsBasedSelect: FC<SettingBasedSelectProps> = ({setting}) => {
2  const conf = useSettings({'options': setting});
3
4  if(conf.options.status === 'loading') {
5    return Spinner;
6  }
7  return (
8    <select>
9      {conf.options.setting.value.map((opt) => (<option value={opt.value}>{opt.label}</option>))}
10    </select>
11  );
12} 
13
14
15
16// alternate way to use useSettings:
17import { useSettings } from 'mystique/hooks/useSettings';
18import { FC } from 'react';
19
20export const SampleFieldUseSettings: FC = () => {
21  const settings = useSettings({ key: 'i18n.languages' });
22
23  if (settings.key.status === 'loading') {
24    return <div>loading</div>;
25  }
26
27  return (
28    <div>
29      <h1>SampleFieldUseSettings</h1>
30      <h4>JSON.stringify(settings.key.result?.value):</h4>
31      <div>{JSON.stringify(settings.key.result?.value)}</div>
32      <h4>settings.key.result?.value.accountDefaultLanguage</h4>
33      <div>{settings.key.result?.value.accountDefaultLanguage}</div>
34    </div>
35  );
36};
37
38
39
40
41

Language: tsx

Name: Code sample of useSettings

Description:

[Warning: empty required content area]

getSettings

For cases where a hook is not a good fit, a Promise-based variant of 

`useSettings`
 is provided in 
`mystique/hooks/getSettings`
.

An example can be found in here

useQuery and useRest

For most cases we strongly encouraged letting the UX framework build and run the query based on the manifest configuration, for performance and complexity reasons, but there are cases in which a single query is not enough to gather all of the data required for a given page. This is especially true for cases where the result of one query is needed to build the follow-up query.

The useQuery is available to components for those edge cases.

The useRest example can be found here.

A simple useQuery Example
1import { useQuery } from 'mystique/hooks/useQuery';
2import { Connection } from 'mystique/types/common';
3import { FC } from 'react';
4
5interface NetworkNode {
6  id: string;
7  ref: string;
8  status: string;
9}
10
11interface NetworkResult {
12  NetworkResult: Connection<NetworkNode>;
13}
14
15const networkQuery = `
16query getNetworks{
17    networks(first:5){
18        edges{
19            node{
20                id
21                ref
22                status
23                type
24            }
25        }
26    }
27}`;
28
29export const SampleFieldHooks2: FC = () => {
30  const [res] = useQuery<NetworkResult>(networkQuery);
31
32  return (
33    <div>
34      <h1>SampleFieldHooks2</h1>
35      <h4>Example of useQuery without any query input vars</h4>
36      <h4>JSON.stringify(res.data)</h4>
37      <div>{JSON.stringify(res.data)}</div>
38    </div>
39  );
40};
41

Language: tsx

Name: A simple useQuery Example

Description:

A Simple useQuery without any query input variables.

An example of retrieving the data and displaying it on the front end.

useQuery Example with useAuth() as query variable
1import { useQuery } from 'mystique/hooks/useQuery';
2import { Connection } from 'mystique/types/common';
3import { useAuth } from 'mystique/hooks/useAuth';
4import { FC } from 'react';
5
6interface OrderNode {
7  id: string;
8  ref: string;
9  status: string;
10  type: string;
11  retailerId: { id: string };
12}
13
14interface OrderResult {
15  OrderResult: Connection<OrderNode>;
16}
17
18const orderQuery = `
19query getOrders($retailerId: [Int!]){
20    orders(retailerId:$retailerId){
21        edges{
22            node{
23                id
24                ref
25                status
26                type
27                retailer{ id }
28            }
29        }
30    }
31}`;
32
33export const SampleFieldHooks3: FC = () => {
34  const auth = useAuth();
35  const [res] = useQuery<OrderResult>(orderQuery, {
36    retailerId: auth.context.current.contextId,
37  });
38
39  return (
40    <div>
41      <h1>SampleFieldHooks3 - auth as variable</h1>
42      <h4>Example of useQuery with useAuth() as a query variable</h4>
43      <h4>JSON.stringify(res.data)</h4>
44      <div>{JSON.stringify(res.data)}</div>
45    </div>
46  );
47};
48

Language: tsx

Name: useQuery Example with useAuth() as query variable

Description:

Example of useQuery with useAuth() as a query variable

 Example of useQuery to handle 'edges' nodes in the result.
1import { useQuery } from 'mystique/hooks/useQuery';
2import { Connection } from 'mystique/types/common';
3import { useAuth } from 'mystique/hooks/useAuth';
4import { FC } from 'react';
5
6interface OrderItemNode {
7  id: string;
8  ref: string;
9  quantity: string;
10}
11
12interface OrderNode {
13  id: string;
14  ref: string;
15  status: string;
16  type: string;
17  retailerId: { id: string };
18  OrderItems: Array<OrderItemNode>;
19  // alternative way to declare OrderItem:
20  //  OrderItems: Array<{ id: string; ref: string; quantity: string }>;
21}
22
23interface OrderResult {
24  OrderResult: Connection<OrderNode>;
25}
26
27const orderQuery = `
28query getOrders($retailerId: [Int!]){
29    orders(retailerId:$retailerId){
30        edges{
31            node{
32                id
33                ref
34                status
35                type
36                retailer{ id }
37                items{
38                    edges{
39                        node{
40                            id
41                            ref
42                            quantity
43                        }
44                    }
45                }                
46            }
47        }
48    }
49}`;
50
51export const SampleFieldHooks4: FC = () => {
52  const auth = useAuth();
53  const [res] = useQuery<OrderResult>(orderQuery, {
54    retailerId: auth.context.current.contextId,
55  });
56
57  return (
58    <div>
59      <h1>SampleFieldHooks4 - auth as variable with edges within the result</h1>
60      <h4>
61        Example of useQuery with Auth as the query variable. edges in the
62        result.
63      </h4>
64      <h4>JSON.stringify(res.data)</h4>
65      <div>{JSON.stringify(res.data)}</div>
66    </div>
67  );
68};
69

Language: tsx

Name: Example of useQuery to handle 'edges' nodes in the result.

Description:

[Warning: empty required content area]
Example of useQuery using contextEntity as input variable
1import { useQuery } from 'mystique/hooks/useQuery';
2import { Connection } from 'mystique/types/common';
3import { FC } from 'react';
4
5interface LocationNode {
6  id: string;
7  ref: string;
8  status: string;
9}
10
11interface LocationResult {
12  locations: Connection<LocationNode>;
13}
14
15const locationQuery = `
16query getLocations($locationRef:[String]){
17    locations(ref:$locationRef){
18        edges{
19            node{
20                id
21                ref
22                status
23            }
24        }
25    }
26}`;
27
28
29export const SampleFieldHooks5: FC = ({ entityContext }) => {
30  const [res] = useQuery<LocationResult>(locationQuery, {
31    locationRef: entityContext?.[0].entity.ref,
32  });
33
34  return (
35    <div>
36      <h1>SampleFieldHooks5: useQuery using entityContext as input vars</h1>
37      <h4>Example of useQuery using contextEntity as input vars</h4>
38      <h4>{JSON.stringify(res.data)}</h4>
39      <div>{JSON.stringify(entityContext)}</div>
40    </div>
41  );
42};
43

Language: tsx

Name: Example of useQuery using contextEntity as input variable

Description:

[Warning: empty required content area]
Example of useQuery and use Map function to display the data
1import { useQuery } from 'mystique/hooks/useQuery';
2import { Connection } from 'mystique/types/common';
3import { useAuth } from 'mystique/hooks/useAuth';
4import { FC } from 'react';
5
6interface OrderItemNode {
7  id: string;
8  ref: string;
9  quantity: string;
10}
11
12interface OrderNode {
13  id: string;
14  ref: string;
15  status: string;
16  type: string;
17  retailerId: { id: string };
18  OrderItems: Array<OrderItemNode>;
19  // alternative way to declare OrderItem:
20  //  OrderItems: Array<{ id: string; ref: string; quantity: string }>;
21}
22
23interface OrderResult {
24  orders: Connection<OrderNode>;
25}
26
27const orderQuery = `
28query getOrders($retailerId: [Int!]){
29    orders(retailerId:$retailerId){
30        edges{
31            node{
32                id
33                ref
34                status
35                type
36                retailer{ id }
37                items{
38                    edges{
39                        node{
40                            id
41                            ref
42                            quantity
43                        }
44                    }
45                }                
46            }
47        }
48    }
49}`;
50
51export const SampleFieldUseQueryMap: FC = () => {
52  const auth = useAuth();
53  const [res] = useQuery<OrderResult>(orderQuery, {
54    retailerId: auth.context.current.contextId,
55  });
56
57  return (
58    <div>
59      <h1>SampleFieldUseQueryMap</h1>
60      <h4>Example of useQuery</h4>
61      <h4>JSON.stringify(res.data)</h4>
62      <div>{JSON.stringify(res.data)}</div>
63      <h4>res.data?.orders.edges.map((row) => </h4>
64      <table border='1'>
65        <tr>
66          <th>orderId</th>
67          <th>orderRef</th>
68        </tr>
69        {res.data?.orders.edges.map((row) => (
70          <tr>
71            <td>{row.node.id}</td>
72            <td>{row.node.ref}</td>
73          </tr>
74        ))}
75      </table>
76    </div>
77  );
78};
79

Language: tsx

Name: Example of useQuery and use Map function to display the data

Description:

[Warning: empty required content area]
Example of useQuery returning a single result
1import { useQuery } from 'mystique/hooks/useQuery';
2import { FC } from 'react';
3
4//
5//  Example of useQuery returning 1 entity
6//
7
8interface LocationNode {
9  id: string;
10  ref: string;
11  status: string;
12}
13
14interface LocationResult {
15  // The var name must be same as the query.
16  locationById: LocationNode;
17  // Since the query will return 1 entity, you do not need to use
18  // Connection<>. but it still returning result...
19  //locationById: Connection<LocationNode>;
20}
21
22const locationQuery = `
23query getLocationById($locationId:ID!){
24    locationById(id:$locationId){
25        id
26        ref
27        status
28    }
29}`;
30
31export const SampleFieldUseQuerySingleResult: FC = ({ entityContext }) => {
32  const [res] = useQuery<LocationResult>(locationQuery, {
33    locationId: entityContext?.[0].entity.id,
34  });
35  return (
36    <div>
37      <h1>SampleFieldUseQuerySingleResult: returning 1 entity in Result</h1>
38      <h4>
39        returning 1 entity with <b>any</b> Type
40      </h4>
41      <h4>JSON.stringify(res):</h4>
42      <div>{JSON.stringify(res)}</div>
43      <h4>JSON.stringify(res.data):</h4>
44      <div>{JSON.stringify(res.data)}</div>
45      <h4>res.data?.locationById.ref:</h4>
46      <div>{res.data?.locationById.ref}</div>
47      <h4>res.data?.locationById.id:</h4>
48      <div>{res.data?.locationById.id}</div>
49      <h4>res.data?.locationById.status:</h4>
50      <div>{res.data?.locationById.status}</div>
51    </div>
52  );
53};
54

Language: tsx

Name: Example of useQuery returning a single result

Description:

[Warning: empty required content area]
getQuery and getRest

For cases where a hook is not a good fit, a Promise-based variant of each is provided in 

`mystique/hooks/getQuery`
 and 
`mystique/hooks/getRest`
 respectively.

An example of

`getQuery`
can be found here


getApiDownload

There are a few Fluent REST API endpoints that produce a file.

The getApiDownload hook (module 

`mystique/hooks/getApiDownload`
) allows a component to retrieve this data in the form of a blob, which can then either be rendered or downloaded as required.


useData

The useData hook provides direct access to the page query response and variables.

It can be used to build components that alter the page query in response to user interaction, like the list filter.

1import { useData } from 'mystique/hooks/useData';
2import { FC } from 'react';
3
4export const SampleFieldUseData: FC = () => {
5  const data = useData();
6
7  return (
8    <div>
9      <h1>SampleFieldUseData</h1>
10      <h4>JSON.stringify(data):</h4>
11      <div>{JSON.stringify(data)}</div>
12      <h4></h4>
13      <div></div>
14    </div>
15  );
16};
17

Language: tsx

Name: Example of useData

Description:

[Warning: empty required content area]


useUserActions and useUserActionForm

User actions are used to indicate in the workflow that a ruleset should appear in the UI. This usually take the form of a button which, if required, presents a modal to capture any extra information needed to process the action.

The useUserActions hook allows an SDK developer to get a list of the available user actions on any entity returned by the page query.

By default, it will return user actions for the first entity found at the current dataSource root (i.e. the 

`data`
 object passed into this component), but this can be changed using the 
`path`
 parameter (in the form of a 
`JSONPath`
 relative to the current dataSource root).

The useUserActionForm generates a form for a named user action. The target entity is chosen using the same logic as the useUserActions hook.

Fluent Commerce staff

Fluent Commerce staff

Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.

Fluent Logo