All Projects → FactorialComplexity → react-redux-controllers

FactorialComplexity / react-redux-controllers

Licence: MIT license
Microframework for structuring code of React/Redux applications

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to react-redux-controllers

pipes
Репозиторий, который сам считает сколько у него звёзд.
Stars: ✭ 25 (+92.31%)
Mutual labels:  actions
dependent-issues
📦 A GitHub Action for marking issues as dependent on another
Stars: ✭ 83 (+538.46%)
Mutual labels:  actions
fullstack-grpc
gRPC web with REST gateway and interceptors and example web app with envoy proxy
Stars: ✭ 42 (+223.08%)
Mutual labels:  actions
gh-action-community
GitHub Action for the Community, from welcoming first timers to badges
Stars: ✭ 24 (+84.62%)
Mutual labels:  actions
svgo-action
Automatically run SVGO with GitHub Actions
Stars: ✭ 18 (+38.46%)
Mutual labels:  actions
viewts
Display PCR, DTS, PTS, bitrate, jitter of a mpeg TS.
Stars: ✭ 46 (+253.85%)
Mutual labels:  actions
xray-action
... a GitHub action to import test results into "Xray" - A complete Test Management tool for Jira.
Stars: ✭ 16 (+23.08%)
Mutual labels:  actions
changelog-reader-action
A GitHub action to read and get data from the CHANGELOG.md file 🚀
Stars: ✭ 68 (+423.08%)
Mutual labels:  actions
github-create-release-action
Create a GitHub release from a Tag
Stars: ✭ 33 (+153.85%)
Mutual labels:  actions
shazam
⚡️ An opinionated and usefull react app management
Stars: ✭ 17 (+30.77%)
Mutual labels:  redux-application
staticcheck-action
Staticcheck's official GitHub Action
Stars: ✭ 47 (+261.54%)
Mutual labels:  actions
jacoco-report
Github action that publishes the JaCoCo report as a comment in the Pull Request
Stars: ✭ 31 (+138.46%)
Mutual labels:  actions
release-helper
🤖 A GitHub Action that help you publish release.
Stars: ✭ 27 (+107.69%)
Mutual labels:  actions
ssh2actions
Connect to GitHub Actions VM via SSH for interactive debugging
Stars: ✭ 62 (+376.92%)
Mutual labels:  actions
setup-timezone
setup timezone for actions
Stars: ✭ 20 (+53.85%)
Mutual labels:  actions
assign-one-project-github-action
Automatically add an issue or pull request to specific GitHub Project(s) when you create and/or label them.
Stars: ✭ 140 (+976.92%)
Mutual labels:  actions
nitro
🔥 NITRO: Nitrogen Web Framework
Stars: ✭ 45 (+246.15%)
Mutual labels:  actions
action-python-poetry
Template repo to quickly make a tested and documented GitHub action in Python with Poetry
Stars: ✭ 85 (+553.85%)
Mutual labels:  actions
gradle-actions
Github Actions for Gradle
Stars: ✭ 29 (+123.08%)
Mutual labels:  actions
floatly
An extension that adds a floating button for browser quick actions
Stars: ✭ 32 (+146.15%)
Mutual labels:  actions

React/Redux Controllers

Build Status

NOTE: This guide assumes the reader is familiar with Redux and React.

This microframework was created for organizing the code of React/Redux applications. It is important to understand that it does not introduce any new fundamental concepts to how regular React/Redux application works. The goal is to provide the utilities for structuring React/Redux code in a way, that makes it more readable, manageable and reusable.

This is achieved by two essential primitives:

And one small, but important utility class:

NOTE: Action in fact can be used in any Redux application separately from the rest of the framework. Action class itself has zero dependencies.

Installation

The library is available as a package on NPM:

npm install --save react-redux-controllers

Usage

In order to make it work you need to replace Redux versions of createStore() and combineReducers() with ones provided by current package. I.e. basically replace :

import { createStore, combineReducers } from 'redux'

With:

import { createStore, combineReducers } from 'react-redux-controllers'

NOTE: If you use require() modify the code above accordingly.

Any regular Redux code will continue to work. These functions call their vanilla Redux counterparts under the hood. They do exactly the same, unless you start passing Controller instances into combineReducers() additionally to regular reducers.

Full API Documentation

Controller

As the name of the library implies, the central concept is Controller. However, this is not a controller as in MVC. It is better to think of it as a "data controller", responsible for managing the certain part of the application state. This includes:

  • Sending relevant actions in response to certain related events.
  • Modifying the state by providing the relevant reducer.
  • Providing access and if necessary transforming the data in the managed part of the state.

Developers utilize controllers by subclassing the Controller class provided by the framework. Instances of the Controller subclasses should then be mounted into the Redux store. This is done by passing them to combineReducers() in place of regular reducer functions.

const reducer = combineReducers({
  todo: new ToDoController()
})

Container

Controllers encapsulate all the data processing logic, but it is up to Containers to connect it to the view layer. This is what you connect() for in traditional Redux application. And in fact Container() calls it under the hood. However, instead of requiring to write the boring mapToState and mapToDispatch stuff, we will just connect it to the Controller referenced by path where it was mounted.

import { Container } from 'react-redux-controllers'

class ToDo extends Component {
  // ...
}

export default Container(ToDo, "todo.*");

Behind the scene this automatically maps the whole portion of state tree at state.todo to the props of the exported component. However, there are couple of twists that make this more fun:

  • Any method in Controller which starts with $ is considered to be a "selector". It is called whenever the relevant part of the state needs to be mapped: either by Container or with Controller.$() function.
  • Keys in the state that go immediately below the Controller's level can be marked "private" by prepending them with underscore (_). These keys are explicitly ignored by both Container and Controller.$() function.
  • Any method in Controller which start with dispatch is considered to be a "dispatch" method. It can be automatically mapped to the props by Container.

Containers allow a lot of options for controlling what is mapped where. The details can be found in API documentation. Good practive however is to place all of the selector logic into Controller with minimal remapping in Containers.

Example

Here is a quick example of the simple controller to show framework in action.

import { Controller } from 'react-redux-controllers'

class ToDoController extends Controller {
  constructor() {
    super()
    
    // Create new Action and save it into this.actions.add
    this.createAction('add')
  }
  
  // Provides reducer to be used by store
  reducer() {
    const { add } = this.actions
    
    // this.createReducer is just a shortcut to Action.createReducer,
    // so you do not have to import Action
    return this.createReducer(
      add.on((state, text) => ({
        _items: (state._items || []).concat({ text })
      }))
    )
  }

  // Dispatch function. Will be mapped as `add(text)` in Container
  dispatchAdd(text) {
    this.dispatchAction('add', text)
  }

  // Selector function. Will be used to collect data for `props.text` in Container
  $texts(state) {
    return (this.$$(state)._items || []).map((item) => item.text)
  }
}

The component that works with the controller can look this way:

import { Container } from 'react-redux-controllers'

class ToDo extends Component {
  render() {
    const { texts, add } = this.props
    
    return (
      <ul>
        {texts.map((text, i) => (
          <li key={i}>{text}</li>
        ))}
      </ul>
      <button onclick={add("Do something!")}>
        Add
      </button>
    )
  }
}

export default Container(ToDo, "todo.*");
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].