Data Flow

GState could apply the concept of unidirectional data flow like Flux or Redux

React Todo example write with GState

Commands

let nextTodoId = 0;
export const addTodo = (state, text) => {
    const id = nextTodoId++;
    state.set({
        todos: {
            [id]: {
                id,
                text,
                completed: false
            }
        }
    });
};

export const setVisibilityFilter = (state, filter) => {
    state.set({
        filter: filter
    });
};

export const toggleTodo = (state, id) => {
    const completed = state.get(["todos", id, "completed"]);

    state.set({
        todos: {
            [id]: {
                completed: !completed
            }
        }
    });
};

Commands is same with Redux’s reducers. They could be pure functions, take state as parameter, and use state.get to read, state.set to mutate. It is important because you could reuse the command’s business logic for any state context/path. It is also easy for testing:

test("test addToDo command", () => {
    const state = new GState();
    state.set({ todos: {} });

    addToDo(state, "a");
    expect(state.get({ todos: { _: 1 }}))
        .toMatchObject({ todos:[{text: "a", completed: false}]});
});

Queries

import React from "react";
import TodoList from "./TodoList";
import gstate from "./gstate";
import { toggleTodo } from "./actions";

const getVisibleTodos = (todos = [], filter = "SHOW_ALL") => {
    switch (filter) {
        case "SHOW_ALL":
            return todos;
        case "SHOW_COMPLETED":
            return todos.filter(t => t.completed);
        case "SHOW_ACTIVE":
            return todos.filter(t => !t.completed);
    }
};

const TodoListWithState = gstate(
    {
        todos: {
            _: 1
        },
        filter: 1
    },
    (props, data) => {
        return (
            <TodoList
                todos={getVisibleTodos(data.todos, data.filter)}
                onTodoClick={id => toggleTodo(props.state, id)}
            />
        );
    }
);

module.exports = TodoListWithState;

Queries use gstate state declarative high order component(same with Appollo’s graphql or Relay createFragmentContainer) which use state.watch to query information and render stateless components.

results matching ""

    No results matching ""