Mutated data-store for SolidJS, inspired by React-Redux

Related tags

React solid-mutant
Overview

solid-mutant

Mutated data-store for SolidJS, inspired by React-Redux.

Synopsis

Redux relies on immutability and referential equality to allow applications to detect changes. Reducers must not modify state, but return new state with changes. Without a library such as Immer, this is awkward and prone to errors.

Mutant instead allows mutations directly, by automatically wrapping all mutators in an Immer-like proxy provided by SolidJS through the produce method.

Actions

Like Redux, Mutant supports dispatching actions that are just simple objects that the mutators then process.

However, Mutant provides built-in support for thunks, promises and arrays of actions. It will attempt to batch together multiple actions within those to avoid thrashing the UI.

Mutators

As Mutant allows direct mutation of state, the processing of actions can be much simpler.

function mutator(state, action) {
    // handle uninitialized state, see note below for an easier way
    if(!state) {
        state = { value: 0 };
        mutator(state, action);
        return state;
    }

    switch(action.type) {
        case 'increment': {
            state.value++;
            break;
        }
        case 'decrement': {
            state.value--;
            break;
        }
    }
}

let store = createMutantStore(mutator, { value: 0 });

store.dispatch({type: 'increment'});

console.log(store.state.value); // 1

However, without an initial state value, mutators are responsible for creating fresh objects and populating them, and only if there is no initial state.

To make this easier, the mutatorWithDefault method is provided:

const mutator = mutatorWithDefault(
    () => ({value: 0}), // note this is a closure, so a new object is generated
    (state, action) => {
        switch(action.type) {
            case 'increment': {
                state.value++;
                break;
            }
            case 'decrement': {
                state.value--;
                break;
            }
        }
    }
);

Combining Mutators

Furthermore, mutators can be combined to create a larger state via combineMutators:

import { user_mutator, cart_mutator } from "./mutators";

const root_mutator = combineMutators({
    user: user_mutator,
    cart: cart_mutator,
});

const store = createMutantStore(root_mutator, {}); // state will be filled in with defaults

console.log(store.state.cart); // ...

Effects and side-effects

After Dispatching an action, it's often desired to be able to perform side-effects. Side-effects are best to be avoided in mutators themselves.

To provide this, createMutantStore takes a third argument that is simply a function to perform untracked side-effects.

function some_effect(state, action, dispatch) {
    if(action.type == 'increment') {
        // do whatever, send HTTP requests, command websockets, etc.
        console.log("Incremented!");
    }
}

const store = createMutantStore(mutator, {value: 0}, some_effect);

Patching mutators and effects

The Store value provides methods replaceMutator and replaceEffect to hot-patch those during runtime, allowing you to defer loading in your main application logic until logged in, for example.

Usage in SolidJS

Mutant is built directly on SolidJS primitives such as Solid's own createStore, and as such all values within the store are nested signals.

Mutant provides a few functions to insert the Store into your component tree, and access it later.

The Provider component is a thin wrapper for a context provider, such that:

); }">
import { createMutantStore, Provider } from "solid-mutant";

const store = createMutantStore(...);

function App() {
    return (
        <Provider store={store}>
            <AppInner/>
        </Provider>
    );
}

Then deeper in:

dispatch({type: 'increment'})}> {store.state.value} ) }">
function SomeComponent() {
    let store = useStore(), dispatch = useDispatch();

    return (
        <button type="button" onClick={() => dispatch({type: 'increment'})}>
            {store.state.value}
        </button>
    )
}

Selectors

Or if you're familiar with react-redux's selectors:

let value = useSelector(state => state.value);

<div>{value()}</div>

Note that this uses an accessor callback like a regular signal.

Structured Selectors

Furthermore, structured selectors can be used as such:

let stuff = useStructuredSelector({
    a: state => state.some.thing,
    b: state => do_work(state.other.thing),
});

<div>{stuff.a} and {stuff.b}</div>

Unlike the regular selector, "structured" selectors use Object.defineProperty to make accessing property values easier.

The downside of this is that it uses a custom getter that ties into the state.

To use the result of this structured selector as a regular object, splat it like:

import { createStore } from "solid-js/store";
let [local, setLocal] = createStore({ ...stuff });

A createStructuredSelector method exists as well for re-usable structured selectors.

More docs will be added later.

You might also like...

USA Covid-19 Tracker is a mobile-first application built with React and Redux to give precise information about the virus behavior in the United States. Great transitions and user feedback made with plain CSS.

USA Covid-19 Tracker is a mobile-first application built with React and Redux to give precise information about the virus behavior in the United States. Great transitions and user feedback made with plain CSS.

React.js USA Covid-19 Tracker This application allows the public to keep track of the stadistics of the Covid-19 Pandemic in the United Stated. You wi

Oct 25, 2022

Shows how React components and Redux to build a friendly user experience with instant visual updates and scaleable code in ecommerce applications

Shows how React components and Redux to build a friendly user experience with instant visual updates and scaleable code in ecommerce applications

This simple shopping cart prototype shows how React components and Redux can be used to build a friendly user experience with instant visual updates and scaleable code in ecommerce applications.

Feb 1, 2022

A website built with React, Redux, and Tailwind for styling. The project is displaying a list of books, adding, and removing books.

A website built with React, Redux, and Tailwind for styling. The project is displaying a list of books, adding, and removing books.

Bookstore "Bookstore" is a website built with React, Redux, and Tailwind for styling. The project is displaying a list of books, adding, and removing

Dec 19, 2022

Build an App using React, Redux, Node and Sequelize.

Build an App using React, Redux, Node and Sequelize.

Individual Project - Henry Pokémon Objetivos del Proyecto Construir una App utilizando React, Redux, Node y Sequelize. Afirmar y conectar los concepto

Sep 13, 2022

Stocks Market SPA React-Redux Capstone project

Stocks Market SPA React-Redux Capstone project

Stocks Market SPA React-Redux Capstone project Capstone SPA project using React, Redux and API for the stocks market. Displaying stocks market informa

May 20, 2022

Travelers' Hub with React and Redux

Spacex Travelers' Hub with React and Redux This website displays a list of all available SpaceX rockets. Users can book each rocket by clicking the re

Dec 18, 2022

classify store using react js✔

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Dec 10, 2021

Classify Store in React JS 😃

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Nov 22, 2021

A state management library for React, heavily inspired by vuex

A state management library for React, heavily inspired by vuex

Vuex - But for React! ⚛ If you know vuex, you know it's as close as we get to a perfect state management library. What if we could do this in the reac

Sep 8, 2022
Owner
Lantern
Lantern Communications Platform
Lantern
Redux-todos - simple react, redux todos

Redux Todos Please star this repo if you like ⭐ It's motivates me a lot! Getting Started This project was bootstrapped with Create React App. Stack Av

Ruslan Shvetsov 2 Jul 29, 2022
A web application to search all the different countries in the world and get details about them which can include languages, currencies, population, domain e.t.c This application is built with CSS, React, Redux-Toolkit and React-Router.

A web application to search all the different countries in the world and get details about them which can include languages, currencies, population, domain e.t.c This application is built with CSS, React, Redux-Toolkit and React-Router. It also includes a theme switcher from light to dark mode.

Franklin Okolie 4 Jun 5, 2022
React + Redux starter kit / boilerplate with Babel, hot reloading, testing, linting and a working example app built in

A comprehensive starter kit for rapid application development using React. Why Slingshot? One command to get started - Type npm start to start develop

Cory House 9.8k Dec 22, 2022
Next-gen, highly customizable content editor for the browser - based on React and Redux and written in TypeScript. WYSIWYG on steroids.

ReactPage ReactPage is a smart, extensible and modern editor ("WYSIWYG") for the web written in React. If you are fed up with the limitations of conte

null 9.1k Jan 6, 2023
Starter Antd 4.0 Admin App Mern( Node.js / React / Redux / Ant Design ) Crud & Auth , Dashboard

Starter Antd Admin (Crud & auth) Mern App (Express.js / React / Redux / MongoDB) App built for DigitalOcean MongoDB Hackathon CRM Starter Mern Antd Ad

Salah Eddine Lalami 208 Jan 8, 2023
Boilerplate for Truffle, Web3.js, React, Redux Toolkit

Truffle, React, Redux Toolkit, Web3.js boilerplate What it's for Currently, it's a nightmare and takes forever trying to get React working with Truffl

Adrian Delgado Ξ 29 Jun 9, 2022
This command line helps you create components, pages and even redux implementation for your react project

react-help-create This command line helps you create components, pages and even redux implementation for your react project. How to install it? To ins

Omar 27 Dec 10, 2022
Redux-Toolkit example with React Hooks CRUD Application, Axios, Rest API, Bootstrap

Redux-Toolkit CRUD example with React Hooks, Axios & Web API Build Redux-Toolkit CRUD application with React Hooks and Rest API calls in that: Each it

null 69 Dec 27, 2022
A React Native starter template project with built-in navigation & redux toolkit.

react-native-template A React Native starter template project with built-in navigation & redux toolkit. What's included? @react-native-async-storage/a

Manish Bista 8 Oct 29, 2022
Netflix clone app with React.js and Redux

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Moustapha Mahmoud 5 Dec 9, 2022