
Security News
Crates.io Implements Trusted Publishing Support
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
react-habitat
Advanced tools
React Habitat is designed for integrating React with your CMS using the DOM as the interface. It's based of some basic container programming principles and brings peace and order to multi page apps.
This framework exists so you can get on with the fun stuff!
You should use React Habitat any time there is a framework or CMS rendering your HTML and you want one or multiple React components on the page(s). For example sometimes there are only sections of your page that you want to be a React Component, then this framework is perfect for that.
The idea behind this is that, rather than trying to initiate one or many React components; by either hard coding or using a Router. You switch it around so components "new up" themselves when required.
React Habitat works great with:
Typically if you're building a full-on one page React app that yanks data from restful API's... then this framework isn't really going to bring much benefit to you. However you are definitely invited to use it if you want to.
We highly recommend you use something like WebPack or Browserify when using this framework.
Install with Node Package Manager (NPM)
npm install --save-dev react-habitat
This assumes that you’re using npm package manager with a module bundler like Webpack or Browserify.
If you don’t yet use npm or a modern module bundler, and would rather prefer a single-file UMD build that makes ReactHabitat
available as a global object, you can grab a pre-built version from the dist folder.
Using ES5? Read the ES5 version here.
The basic pattern for integrating React Habitat into your application is:
This getting started guide walks you through these steps for a simple React application. This document assumes you already know:
The class must extend ReactHabitat.Bootstrapper
and is intended to be an entry point of your bundled app. So if you're using something like webpack or browserify then this is file to point it too.
In the constructor() of the class you need to register your React components with it and then set the container. The container is later bound to the DOM automatically so your React components self-initiate.
In React Habitat, you'd register a component for a key something like this
container.register('SomeReactComponent', SomeReactComponent);
So for our sample application we need to register all of our components (classes) to be exposed to the DOM so things get wired up nicely.
import ReactHabitat from 'react-habitat';
import SomeReactComponent from './SomeReactComponent';
import AnotherReactComponent from './AnotherReactComponent';
class MyApp extends ReactHabitat.Bootstrapper {
constructor(){
super();
// Create a new container builder
var container = new ReactHabitat.Container();
// Register your top level component(s) (ie mini/child apps)
container.register('SomeReactComponent', SomeReactComponent);
container.register('AnotherReactComponent', AnotherReactComponent);
// Finally, set the container
this.setContainer(container);
}
}
// Always export a 'new' instance so it immediately evokes
export default new MyApp();
You can also register multiple component's all at once with registerAll
like this
container.registerAll({
'SomeReactComponent', SomeReactComponent,
'AnotherReactComponent', AnotherReactComponent
});
If you are using Redux
You will need to use a different container. Please install & configure the react-habitat-redux library. Then continue with step 2 below.
During the web application execution you will want to make use of the components you registered. You do this by resolving them in the DOM from a scope.
When you resolve a component, a new instance of the object gets created (Resolving a component is roughly equivalent to calling 'new').
To resolve new instances of your components you need to attach a data-component
attribute to a div
or a span
element in the HTML. These elements should always
remain empty. Any child components should be nested inside the React components themselves.
Set the data-component
value to equal a component name you have registered in the container.
For instance:
<div data-component="SomeReactComponent"></div>
Will be resolved by the following registration.
container.register('SomeReactComponent', SomeReactComponent);
So, for our sample app we would do something like this
<html>
<body>
<div data-component="SomeReactComponent"></div>
<script src="myBundle.js" />
</body>
</html>
When you view this page you will see a instance of SomeReactComponent
automatically rendered in the div's
place. In fact, you can add as many as you like and it will render multiple instances.
For example. This is perfectly valid.
<html>
<body>
<div data-component="SomeReactComponent"></div>
<div data-component="SomeReactComponent"></div>
<div data-component="SomeReactComponent"></div>
<script src="myBundle.js" />
</body>
</html>
Will render 3 instances of your component.
Note It's important that the output built javascript file is included at the end of the DOM just before the closing tag.
Resolving and registering components alone is not all that special, but passing data to it via html attributes is pretty useful. This allows the backend to easily pass data to your components in a modular fashion.
To set props you have a few choices. You can use all of these or only some (they merge) so just use what's suits you best for setting properties.
Set component props via a JSON string on the data-props
attribute.
For example
<div data-component="SomeReactComponent" data-props='{"title": "A nice title"}'></div>
Set an component prop via prefixing attributes with data-prop-
.
For example
data-prop-title
would expose title
as a property inside the component.
There are two important things to note when setting these attribute type properties:
data-prop-my-title
would expose myTitle
as a property in the component.data-prop-my-bool="true"
would expose the value of true
, NOT the string representation "true"
.Simple Example
<div data-component="SomeReactComponent"
data-prop-title="A nice title"
data-prop-show-title="true">
</div>
Would expose props as
class SomeReactComponent extends React.Component {
constructor(props) {
super(props);
props.title === "A nice title"; //> true
props.showTitle === true; //> true
}
render() {
return <div>{ this.props.showTitle ? this.props.title : null }</div>;
}
}
JSON Example
<div data-component="SomeReactComponent"
data-prop-person="{'name': 'john', 'age': 22}">
</div>
Would expose as
class MyReactComponent extends React.Component {
constructor(props) {
super(props);
return (
<div>
Name: {this.props.person.name}
Age: {this.props.person.age}
</div>
);
}
}
Set an component prop with type [number] via prefixing attributes with data-n-prop-
.
This is handy if you know that a property is always going to be a number or float.
For example data-n-prop-temperature="33.3"
would expose the float value of 33.3 and not the string representation '33.3'.
See data-prop- above for notes on defining property names.
Referenced a global variable in your component prop via prefixing attributes with data-r-prop-
.
This is handy if you need to share properties between habitats or you need to set JSON onto the page.
For Example
<script>
var foo = window.foo = 'bar';
</script>
<div data-component="SomeReactComponent" data-r-prop-foo="foo"></div>
See data-prop- above for notes on defining property names.
It can be handy to pass values back again, particularly for inputs so the backend frameworks can see any changes or read data.
Every React Habitat instance is passed in a prop named proxy
, this is a reference the original dom element.
Please note only <inputs />
are left in the DOM by default. To keep a generic element in the DOM, set the data-habitat-no-replace="true"
attribute.
So for example, we could use proxy
to update the value of an input like so
<input id="personId" type="hidden" data-component="personLookup" />
Somewhere inside the component
this.props.proxy.value = '1234'
Sometimes you may additionally need to call this.props.proxy.onchange()
if you have other scripts listening for this event.
Using ES5? Read the ES5 version here.
You can set a custom css class on the habitat element by setting the data-habitat-class
attribute on the target element.
Example
<div data-component="MyComponent" data-habitat-class="my-css-class"></div>
Will result in the following being rendered
<div data-habitat="C1" class="my-css-class">...</div>
Default: 'data-component'
By default React Habitat will resolve components via the data-component
attribute. You can configure this by assigning
the componentSelector
property in your constructor.
It will accept any string containing any valid attribute name.
Example
class MyApp extends ReactHabitat.Bootstrapper {
constructor(){
super();
this.componentSelector = 'data-myComponents';
}
}
To unload the container and remove all React Habitat instances. Call the dispose()
method.
Example
class MyApp extends ReactHabitat.Bootstrapper {
constructor(){
super();
...
this.dispose();
}
}
Please don't hesitate to raise an issue through GitHub or open a pull request to show off your fancy pants coding skills - we'll really appreciate it!
Part Business. Part Creative. Part Technology. One hundred per cent digital.
Pioneered in Australia, Deloitte Digital is committed to helping clients unlock the business value of emerging technologies. We provide clients with a full suite of digital services, covering digital strategy, user experience, content, creative, engineering and implementation across mobile, web and social media channels.
http://www.deloittedigital.com/au
Copyright (C) 2015, Deloitte Digital. All rights reserved.
React Habitat can be downloaded from: https://github.com/DeloitteDigitalAPAC/react-habitat
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[0.3.0]
FAQs
A React DOM Bootstrapper designed to harmonise a hybrid application
The npm package react-habitat receives a total of 1,709 weekly downloads. As such, react-habitat popularity was classified as popular.
We found that react-habitat demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
Research
/Security News
Undocumented protestware found in 28 npm packages disrupts UI for Russian-language users visiting Russian and Belarusian domains.
Research
/Security News
North Korean threat actors deploy 67 malicious npm packages using the newly discovered XORIndex malware loader.