A higher-order component's role is to wrap a regular component to pass it a specific prop (such as a list of posts, the current user, the Router object, etc.). You can think of HOCs as specialised assistants that each hand the component a tool it needs to do its job.
The first argument of set is the component's name, the second is the component itself, and any successive arguments will be interpreted as higher-order components and wrapped around the component.
For example, this is how you'd pass the currentUser object to the Logo component:
There are a few subtle differences between registering a component with register
and the more standard export default Foo
and import Foo from './Foo.jsx'
ES6 syntax.
First, you can only override a component if it's been registered using register
. This means that if you're building any kind of theme or plugin and would like end users to be able to replace specific components, you shouldn't use import/export.
Second, both techniques also lead to different results when it comes to higher-order components (more on this below). If you write export withCurrentUser(Foo)
, the withCurrentUser
function will be executed immediately, which will trigger an error because the fragment it depends on isn't properly initialised yet.
On the other hand, register
doesn't execute the function (note that we write withCurrentUser
and not withCurrentUser()
), delaying execution until app's initialisation.
But what about HoC functions that take arguments? For example if you were to write:
The withList(options)
would be executed immediately, and you would have no way of overriding the options object later on (a common use case being overriding a fragment).
For that reason, to delay the execution until the start of the app, you can use the following alternative syntax:
You can add new HOCs to the already registered components any time by using the addHocs
method.
React as a UI library puts a lot of emphasis on components. BlueBase stores components which can be dynamically used and replaced. This plays a major role in creating a pluggable and modular system.
There are many ways to register new components in BlueBase:
The easiest way to add a new component to BlueBase is to use the 'components' property of your plugin:
Note that this may replace any existing components registered with same name.
You can add new Components anywhere in the code by calling the set method of ComponentRegistry:
resolve
methodIn order to access a BlueBase component, just use the resolve
method of Component Registry.
This will return a component wrapped in all the HOCs, and will receive a styles
prop that has all the themed styles.
But in order to get access this component in your code, you will need to use a BlueBaseConsumer component to access BB
context first. This is how the final code may look like:
This adds unnecessarily long and repetitive code. Not to mention the overall ugliness and unreadability. To solve this problem, we export a helper function called getComponent
.
getComponent
functionThe getComponent
function returns a component from BlueBase context. By using this function we can rewrite the example above as:
See how this makes the code much more developer friendly.
It is also possible to get a typed component by providing it props interface:
To make it even more convenient, we export some basic components out of box. This helps developers not only write even less code, but also port react-native apps to BlueBase by just changing the import statement.
Sometimes, you may need to have fallback components. So if they desired component is not found, a back up component can be used. In BlueBase it is very easy to achieve this. Just provide multiple arguments to the resolve function.
The first param acts as the key of the desired, with the following ones acting at fallback components in sequence.
So in the example above, first BlueBase will try to find AnimatedLogo
. If it doesn't exist, BlueBase will look for SingleColorLogo
. If even that isn't found, it will try to get Logo
component.
This works with the getComponent
function. So the code above can be written as:
As explained in the above, the resolve method returns a component wrapped in the registered HOCs, and styles. But sometimes, you may need to access the raw component that was originally registered.
For that reason, BlueRain provides a getValue
method that lets you access the unwrapped “raw” component.
Note that, we used the await
keyword. This is because the getValue method will return the component wrapped in a promise. This is because some components may in different bundles (because of code splitting).
Each component in BlueBase has the following properties:
Key
Type
Description
key
string
The key is used as an ID.
value
React.ComponentType
The raw React component. This may also be a promise (for code splitting) that resolves a React component.
preload
boolean
(optional) (Default = false) Should this component be preloaded at app initialization. This is useful for components that are wrapped in promises (for code splitting).
hocs
Array
An array of React Higher Order Components. At runtime, each component is resolved with wrapping raw component in all HOCs in this array.
styles
{ [string: key]: Styles }
An object containing key value pairs of style rules. Each rule maybe a ViewStyle
, TextStyle
or an ImageStyle
.
source
ComponentSource
This property represents the source that registered this component.