---
title:
  "Using globalProps to make it easier to share data in React.js applications"
description:
  "Using globalProps to make it easier to share data in React.js applications"
canonical_url: "https://www.bigbinary.com/blog/global-props"
markdown_url: "https://www.bigbinary.com/blog/global-props.md"
---

# Using globalProps to make it easier to share data in React.js applications

Using globalProps to make it easier to share data in React.js applications

- Author: Deepak Jose
- Published: February 6, 2024
- Categories: React, Rails

### Our technology stack for Neeto

We are building [neeto](https://neeto.com), and our technology stack is quite
simple. On the front end, we use React.js. On the backend we use Ruby on Rails,
PostgreSQL, Redis and Sidekiq.

The term `globalProps` might not ring a bell for most people. It was coined by
the BigBinary team for our internal use. `globalProps` is data that is directly
retrieved from our backend and assigned to the browser global object that's
`window`. To view the global props, we can type `globalProps` in the browser
console, which prints out useful information set by the backend service.

<img alt="desktop view" src="/blog/images/images_used_in_blog/2024/global-props/global-props-console.png">

### How is `globalProps` implemented

To understand where the `globalProps` came from and how it works, we need to
examine the [React-Rails](https://github.com/reactjs/react-rails) gem. It uses
Ruby on Rails asset pipeline to automatically transform JSX into Ruby on Rails
compatible assets using the Ruby Babel transpiler.

`react_component` helper method takes a component name as the first argument,
`props` as the second argument and a list of `HTML attributes` as the third
argument. The documentation has more
[details](https://github.com/reactjs/react-rails/blob/master/docs/view-helper.md).

```erb
<%= react_component("App", get_client_props, { class: "root-container" }) %>
```

### Limitations of the default behavior

In the `react-rails` gem, the hash is set as the props of the component
specified in the `react_component` method by default. In the example above, the
hash returned by the `get_client_props` method is passed as props to the `App`
component in the front end.

The limitation of this approach is that we need to pass down globalProps through
all the components by prop-drilling or React Context.

##### The concept of nanos

At neeto, anything that does not contain product-specific business logic and can
be extracted into a reusable tool is extracted into an independent package. We
call them nanos.

You can read more about it in our blog on how
[nanos make Neeto better](https://blog.neeto.com/p/nanos-make-neeto-better).

##### Limitations in accessing the props by nanos and utility functions

The issue with the above approaches in handling the props is that it won't be
directly available in utility functions or nano. We explicitly need to pass it
as arguments to utility functions after prop drilling. If we use React Context,
it can only be accessed in React components or hooks, it cannot be accessed in
utility functions. Also, we cannot directly obtain the reference of the Context
within the nanos.

##### Why we didn't chose environment variables

Some of the variables inside the `globalProps` are environment variables, which
is usually accessed as `process.env.VARIABLE_NAME`. If we set environment
variables, they will be hardcoded into the JavaScript bundle at the time of
bundling. This implies that whenever we need to change the environment variable,
we must trigger a redeployment.

### The solution is `globalProps`

The advantage of `globalProps` over these approaches is, it's accessible
everywhere since it's in the browser global object window. All the nanos and
utility functions that we integrate into the application have seamless access to
the props without any extra step of wiring.

### Seeding the hash at the backend into the browser's global object, window

Seeding the hash at the backend into the browser's global object, window, is
accomplished using the above-mentioned helper method, `react_component`. As we
discussed earlier, an HTML node is created that contains `data-react-class`
representing the component name and`data-react-props` attribute representing the
hash we passed from the backend as an HTML-encoded string.

<img alt="desktop view" src="/blog/images/images_used_in_blog/2024/global-props/element-console.png" >

### Decode the HTML-encoded string into JavaScript object

The next step is to decode the HTML-encoded string and parse it into a
JavaScript object. The hash is read from the `root-container` HTML node and
parsed into a JavaScript object.

```js
const rootContainer = document.getElementsByClassName("root-container")[0];

const reactProps = JSON.parse(rootContainer?.dataset?.reactProps || "{}");
```

### Convert the case of the keys in the object

The JavaScript object that we have obtained have the keys in snake case. We will
convert them into camel case using the helper method
[keysToCamelCase](https://github.com/bigbinary/neeto-cist/blob/b4375525ac5ffbb0aeb6548cc64d3970379493ee/docs/pure/objects.md#keystocamelcase).

We convert the case because React prefers camel case keys, while Rails prefers
snake case keys.

```js
const globalProps = keysToCamelCase(reactProps);
```

### Deepfreeze the global props

Additionally, we take an extra step to deep-freeze the global props object,
ensuring immutability. The helper function used here is
[deepFreezeObject](https://github.com/bigbinary/neeto-cist/blob/b4375525ac5ffbb0aeb6548cc64d3970379493ee/docs/pure/objects.md#deepfreezeobject).
This prevents modifications to global props from within the product and thus
ensures data integrity when working with different nanos. All these steps are
performed before the initial rendering of the React component.

```js
window.globalProps = globalProps;

deepFreezeObject(window.globalProps);
```

Let's see the final codeblock that seeds the hash at the backend to the
browser's global object.

```js
export default function initializeGlobalProps() {
  const rootContainer = document.getElementsByClassName("root-container");
  const htmlEncodedReactProps = rootContainer[0]?.dataset?.reactProps;

  const reactProps = JSON.parse(htmlEncodedReactProps || "{}");
  const globalProps = keysToCamelCase(reactProps);

  window.globalProps = globalProps;
  deepFreezeObject(window.globalProps);
}
```

If we take a closer look at the content of `globalProps`, we can see that it
carries a lot of data. As discussed earlier this data is useful to other nanos.
Some of the data being passed are appName, honeyBadgerApiKey, organization, user
info, etc.

<img alt="desktop view" src="/blog/images/images_used_in_blog/2024/global-props/global-props-console.png">

## Links

- [Human page](https://www.bigbinary.com/blog/global-props)
