fuse-react v3.0.8
fuse-react
fuse-react
is an abtraction on top of React Component which relieves the pain for those who find Redux overly complicated.
fuse-react
offers a solution to react routing which is more flexible and memory efficient than react-router-dom
Router
fuse-react
Router does everything (and does NOT) that react-router
does
- Memory efficient (render only required component)
- Component lazy load
- Extended Link support (aka mini router) with custom tags
- No wrapping the application
- Nothing else is required but
Switch
andRoute
(works with any React.Component framework)
<Switch>
<Route path="/user" component={async () => import("./UserRoute")} />
</Switch>
FuseReact Router is very similar to react-router
, in fact it mimics the API so the transition will be as smooth as possible.
Unlike react-router
fuse-react router
subscribes to changes and renders only necessary components avoiding render
from the top of the DOM tree.
Switch and Route
To create a router swith do the following
import * as React from "react";
import { Switch, Route } from "fuse-react";
export class UserRoute extends React.Component {
public render() {
return (
<Switch>
<Route path="/user" component={async () => import("./UserRoute")} />
<Route match="/group">Group route</Route>
</Switch>
);
}
}
Switch
object doesn't need to have any parent object unlike react-router
, it can be placed anywhere.
Matching /user/anything/here
<Route path="/user" component={UserRoute} />
Strict match /user
<Route path="/user" exact component={UserRoute} />
Render children
<Route path="/user">I will be rendered</Route>
Access route
object via props in your component
import * as React from "react";
import { Switch, Route } from "fuse-react";
export class UserRoute extends React.Component {
init() {}
public render() {
return <div>User Id: {this.props.match.params.id}</div>;
}
}
Router object instantiation
Via children (simplest)
Match params are not supported here
<Route path="/user">I will be rendered</Route>
Component property as React.Element prototype
This one is the most popular with react-router-dom
<Route path="/user" component={UserRouter} />
Component property as a function (returns React.Element prototype)
<Route path="/user" component={match => UserRouter} />
Component property as a function (returns React.Element)
<Route path="/user" component={match => <UserRouter {...match} />} />
Component property as an async function (lazy load)
Once UserRouter
is lazy loaded, we will try to find default
or the first exports key as a valid React.Component
and apply match
as a property
<Route path="/user" component={async match => import("./UserRoute")} />
Another example with timeout
<Switch placeholder={<div>Loading</div>}>
<Route
path="/listing/a"
component={() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(ListingA);
}, 1000);
});
}}
/>
<Route path="/listing/b" component={() => ListingB} />
</Switch>
Switch Configuration
Instead of passing Route
object it's possible to create a configuration file and pass it to Switch
const config = {
routes: {
"/user": {
component: UserRoute
},
"/group": {
component: async () => import("./UserGroup")
}
}
};
class MyRootComponent extends React.Component {
public render() {
return <Switch config={config} />;
}
}
Links
The Link
object is way more flexible comparing to react-router
's
Importing
import { Link } from "fuse-react";
Regular a
tags
<Link activeClassName="active" to="/user/listing">
list
</Link>
Custom render
render
property accepts active
and navigate
function
<Link
to="/user/add"
render={(active, navigate) => (
<div className={active ? "active" : ""} onClick={navigate}>
To user
</div>
)}
/>
Custom render converts your link into a mini router. You can pass additional property for matching
<Link
to="/user/add"
match="/user"
render={(active, navigate) => (
<div className={active ? "active" : ""} onClick={navigate}>
To user
</div>
)}
/>
In the case above active
is true
when navigated to /user/foobar
, however the navigate
function navigates to /user/add
Navigation
Access navigation from anywhere in your code!
import { navigate, mergeQuery, setQuery } from "fuse-react";
Navigating to path
navigate("/user");
Passing and overriding query arguments
navigate("/user", { foo: "bar" });
// will result in `/user?foo=bar`
Setting query
setQuery({ foo: "bar" });
// will result in `/current-url?foo=bar`
Merging query
// existing url "/user?hello=world"
mergQuery({ foo: "bar" });
// will result in `/user?hello=world&foo=bar`
Additionally setQuery
and mergQuery
accept a second bool argument. Dispatch (update trigger for all Switch
and Link
on scene) won't be triggered when set false
// existing url "/user?hello=world"
mergQuery({ foo: "bar" }, false);
// will result in `/user?hello=world&foo=bar`
A component can "connect" to an individual key in the store and react to its changes.
The framework also offers a router which has some improvements comparing to react-router
@connect({ counter: CountStorage })
class MyUser extends React.Component<{ store: CountStorage }, any> {
public render() {
return <div onClick={}>{this.props.counter.number}</div>;
}
}
The decorator @connect
connects component and its Storage
import { ReactStorage } from "fuse-react";
export class CountStorage extends ReactStorage {
public number;
init() {
this.number = 0;
}
public increase() {
this.number++;
this.notify(); // tells the connected components to trigger an update
}
}
Create your store
import { Store } from "fuse-react";
export class NewStore extends Store {
constructor() {
super();
}
}
Store.create(NewStore);
This class will be instantiated and registered globally
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago