3.0.8 • Published 4 years ago

fuse-react v3.0.8

Weekly downloads
41
License
MIT
Repository
github
Last release
4 years ago

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 and Route (works with any React.Component framework)

diagram

<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

3.0.8

4 years ago

3.0.7

4 years ago

3.0.6

4 years ago

3.0.5

4 years ago

3.0.4

4 years ago

2.0.8

5 years ago

2.0.7

5 years ago

2.0.6

5 years ago

2.0.5

5 years ago

2.0.4

5 years ago

2.0.2

5 years ago

2.0.1

5 years ago

2.0.0

5 years ago

1.0.21

6 years ago

1.0.20

6 years ago

1.0.19

6 years ago

1.0.18

6 years ago

1.0.17

6 years ago

1.0.16

6 years ago

1.0.15

6 years ago

1.0.14

6 years ago

1.0.12

6 years ago

1.0.11

6 years ago

1.0.10

6 years ago

1.0.9

6 years ago

1.0.8

6 years ago

1.0.7

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago