@nathanfaucett/state-immutable-react

connect react components with immutable state stores

Usage no npm install needed!

<script type="module">
  import nathanfaucettStateImmutableReact from 'https://cdn.skypack.dev/@nathanfaucett/state-immutable-react';
</script>

README

js-state-immutable-react

connect react components with immutable state stores

State Stores

import { Map, List } from "immutable";
import state from "./state";

let ID = 0;

const todos = state.createStore("todos", {
    list: List()
});

todos.create = text => {
    let id = ID++;

    todos.updateState(state =>
        state.update("list", list => list.push(Map({ id: id, text: text })))
    );
};

todos.remove = id => {
    todos.updateState(prev => {
        return prev.update("list", list =>
            list.remove(list.findIndex(todo => todo.get("id") === id))
        );
    });
};

export default todos;

Components

import React from "react";
import connect from "@nathanfaucett/state-immutable-react";
import state from "./state";
import todos from "./stores/todos";

// create store for form input
let todoListForm = state.createStore("todoListForm", { text: "" });

class TodoList extends React.Component {
    constructor(props) {
        super(props);

        this.onSubmit = e => {
            e.preventDefault();
            todos.create(this.props.todoListForm.text);
            todoListForm.setState({ text: "" });
        };

        this.onChange = e => {
            todoListForm.setState({ text: e.target.value });
        };
    }
    render() {
        return (
            <div class="TodoList">
                <form onSubmit={this.onSubmit}>
                    <input
                        value={this.props.todoListForm.text}
                        onChange={this.onChange}
                    />
                </form>
                {this.props.todos.list.map(todo => (
                    <p key={todo.id}>{todo.text}</p>
                ))}
            </div>
        );
    }
}

// update TodoList when todos or todoListForm emit an update
// on update adds todos state and todoListForm state to props
export default connect([todos, todoListForm], {
    mapping: (nextState, nextProps, props) => {
        // called on render should extract values from nextState to pass to component props
    },
    shouldUpdate: (prevState, nextState) => {
        // called on update, if returns false cancels update
    }
})(TodoList);