React Hooks in the Component SDK
Author:
Fluent Commerce
Changed on:
15 July 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`
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`
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`
`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`
`mystique/hooks/getRest`
An example of
`getQuery`
getApiDownload
There are a few Fluent REST API endpoints that produce a file.
The getApiDownload hook (module
`mystique/hooks/getApiDownload`
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`
`path`
`JSONPath`
The useUserActionForm generates a form for a named user action. The target entity is chosen using the same logic as the useUserActions hook.