Alfa converts your regular React component into a dependency injected component by injecting application data from a key/value store. Let Alfa handle the data if you use it in different components:
// hello.jsimportReactfrom'react'import{inject}from'alfa'// A stateless functional component.functionHelloMessage(props){// Data is injected as the property of props.return<div>Hello ${props.name}!</div>}exportdefaultinject(HelloMessage,['name'])
inject makes a new component which gets data name from the store and renders HelloMessage internally.
Now let's see how to use the above component in our app:
// index.jsimportReactfrom'react'import{render}from'react-dom'import{inject}from'alfa'importHelloMessagefrom'./hello.js'// Define the root app which renders HelloMessage as a child.constApp=()=>(<div><HelloMessage/></div>)// Create the root component using `inject(Component, data)` with initial data.constRoot=inject(App,{name:'Motoko'})render(<Root/>,document.getElementById('root'))
We don't need to pass the name to HelloMessage component as Alfa gets that value for us from the store. That allows us to quickly move the component around without worrying about how to get the data.
Changing Data
The simplest way to modify the data of the Alfa store is to inject the set function to the component.
// change.jsimportReact,{Component}from'react'import{inject}from'alfa'// A stateful class component.classChangeNameextendsComponent{handleChange=event=>{// Calling `set('mykey', 'my value')` will change the data `mykey`// in store to value `my value`.this.props.set('name',event.target.value)}handleSubmit=event=>{event.preventDefault()}render(){return(<formonSubmit={this.handleSubmit}><label>
Name:
<inputtype="text"value={this.props.name}onChange={this.handleChange}/></label></form>)}}exportdefaultinject(ChangeName,['set','name'],['name'])
As mentioned earlier Alfa makes things explicit. So we need to define the output of the component explicitly if we want to change a value of a key in the global data store (the 3rd argument when calling function inject). Otherwise, Alfa complains we are trying to use set without defining the correct output.
If you run the app and modify the value in the input field, the name on the page do not change? Why?
Because components made by inject does not trigger re-render when we change the injected state in the store. We need to replace it with another function called subscribe.
Subscribing Data
We need to call subscribe instead of inject if we want to trigger the re-render of the component when changing the data. Simply swap inject with subscribe, and you can see the name is changing when you are typing in the input field:
// hello.jsimport{subscribe}from'alfa'//...// Use function `subscribe` instead of `inject`.exportdefaultsubscribe(HelloMessage,['name'])
// change.jsimport{subscribe}from'alfa'//...// Use function `subscribe` instead of `inject`.exportdefaultsubscribe(ChangeName,['set','name'],['name'])
The subscribe has exactly same API as inject. The reason why Alfa provides two functions with slightly different behavior is to let the application developers clear about the type of data they are dealing with - static or dynamic. It not only makes the app more performant but also makes it easier to understand.
You can find the finished version of the above example in the folder examples/hello.
I'm a young Jamaican programmer that has experience in a lot of technologies, such as Angular 2+, Laravel, Yii, HTML/CSS/JS & Android. Currently looking to learn React & Rust.
Effortless React State Management - github.com/lsm/alfa
Guide
Add Alfa to Your React Project
Use
npm
to add it to your package.json.Alternatively, use
yarn
if you prefer:Getting Data for Components
Alfa converts your regular React component into a dependency injected component by
injecting
application data from a key/value store. Let Alfa handle the data if you use it in different components:inject
makes a new component which gets dataname
from the store and rendersHelloMessage
internally.Now let's see how to use the above component in our app:
We don't need to pass the
name
toHelloMessage
component as Alfa gets that value for us from the store. That allows us to quickly move the component around without worrying about how to get the data.Changing Data
The simplest way to modify the data of the Alfa store is to inject the
set
function to the component.As mentioned earlier Alfa makes things explicit. So we need to define the
output
of the component explicitly if we want to change a value of a key in the global data store (the 3rd argument when calling functioninject
). Otherwise, Alfa complains we are trying to useset
without defining the correctoutput
.Now add the
ChangeName
component toApp
:If you run the app and modify the value in the input field, the
name
on the page do not change? Why?Because components made by
inject
does not trigger re-render when we change the injected state in the store. We need to replace it with another function calledsubscribe
.Subscribing Data
We need to call
subscribe
instead ofinject
if we want to trigger the re-render of the component when changing the data. Simply swapinject
withsubscribe
, and you can see the name is changing when you are typing in the input field:The
subscribe
has exactly same API asinject
. The reason why Alfa provides two functions with slightly different behavior is to let the application developers clear about the type of data they are dealing with - static or dynamic. It not only makes the app more performant but also makes it easier to understand.You can find the finished version of the above example in the folder examples/hello.
Wow I don't think I've seen anything as useful as this in a long while!
Thank you for the compliment. Let me know if you have any issues when you try it out.