Last month, I released a library called Extension React that helps you to write React applications by composing a component, adding application logic in services then boxing them in container. But it's still not separate the view and behavior completely. Based on Angular application architecture, I revise Container
concept and named Component
for clarification.
A component controls a patch of screen called a view. You define a component's application logic—what it does to support the view—inside a class. The class interacts with the view through an API of properties and methods. For example:
// dashboard.js
import { Route, Component } from 'ext-react';
import DashboardStore from '~/stores/dashboard';
import DashboardView from './dashboard.view';
@Route('/')
@Component({
componentAs: 'Dashboard',
view: DashboardView,
stores: [DashboardStore]
})
export default class Dashboard {
constructor() {
this.title = 'Dashboard';
}
}
You define a component's view with React Component.
// dashboard.view.jsx
import React, { Component } from 'react'
export default class Dashboard extends Component {
render() {
const { data } = this.props.stores.DashboardStore
return <section className="container-fluid">
<h1>{this.props.Dashboard.title}</h1>
<table className="table table-sm table-hover table-striped">
<thead>
<tr>
<th>Status</th>
<th className="text-sm-right">Total Records</th>
</tr>
</thead>
<tbody>
{data && data.map(item =>
<tr>
<td>{item[0]}</td>
<td className="text-sm-right">{item[1]}</td>
</tr>
)}
</tbody>
</table>
</section>
}
}
Metadata tells Extension React how to process a class and you can attach metadata by using a Component
decorator:
@Component({
componentAs: 'Dashboard',
view: DashboardView,
stores: [DashboardStore]
})
componentAs
: binding theComponent
to theView
, default is 'vm'. That's mean you can access any property or method ofComponent
viathis.props.vm
. For above example, it would bethis.props.Dashboard
.view
: tell React how to render the component.stores
: array of stores that the component requires.