It’s 2017, time to give Redux another thought

It (Redux) helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience”.

What changed in 2017?

Classes

Facebook in their recent post says: “JavaScript classes are now the preferred way to create components in React.”

Decorators

TypeScript

Observables

The approach

npm install statex --save
  • Application State — describe application state as plain objects and arrays.
  • Actions — describe changes in the system as plain objects.
  • Reducer Functions — describe the logic for handling changes as pure functions.
  • Consume Data — using connect function
  • Dispatch Action — using a dispatcher

Application State

interface Todo {
id: string
text: string
completed: boolean
}
interface AppState {
todos: Todo[]
}

Actions

import { Action } from 'statex'export class AddTodoAction extends Action {
constructor(public todo: Todo) { super() }
}
export class RemoveTodoAction extends Action {
constructor(public id: string) { super() }
}

Reducer Functions

const newState = reducer(oldState, action)
const todos = (state = { todos: [] }, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
todos: state.todos.concat(action.todo)
}
case 'REMOVE_TODO':
return {
todos: state.todos.filter(
todo => todo.id != action.id
)
}
default:
return state
}
}
const addTodo = (state, action) => {
return {
todos: (state.todos || []).concat(action.todo)
}
}
const removeTodo = (state, action) => {
return {
todos: (state.todos || []).filter(
todo => todo.id != action.id
)
}
}
class TodoStore {  addTodo(state, action) {
return {
todos: (state.todos || []).concat(action.todo)
}
}
removeTodo(state, action) {
return {
todos: (state.todos || []).filter(
todo => todo.id != action.id
)
}
}
}
@store
class TodoStore {
@action()
addTodo(state: AppState, action: AddTodoAction): AppState {
return {
todos: (state.todos || []).concat(action.todo)
}
}
@action()
removeTodo(state: AppState, action: RemoveTodoAction): AppState {
return {
todos: (state.todos || []).filter(
todo => todo.id != action.id
)
}
}
}

Consume Data

export class TodoListComponent extends React.Component {

render() {
const todos = this.props.todos.map(
todo => <li key={todo.id}>{todo.text}</li>
)

return <ul> {todos} </ul>
}
}
TodoListComponent.propTypes = {
todos: PropTypes.array.isRequired
}
const mapStateToProps = state => ({
todos: state.todos
})
export default connect(
mapStateToProps
)(TodoListComponent)
import * as React from 'react'
import { data, inject } from 'statex/react'

class Props {
@data((state: AppState) => state.todos)
todos: Todo[]
}

@inject(Props)
export class TodoListComponent extends React.Component<Props, {}> {

render() {
const todos = this.props.todos.map(
todo => <li key={todo.id}>{todo.text}</li>
)

return <ul> {todos} </ul>
}
}

Dispatch Action

new RemoveTodoAction(id).dispatch();

To Summarise

A Bonus Point

Want to try?

A final note

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store