Skip to content

Instantly share code, notes, and snippets.

@RocketPuppy
Created October 15, 2020 02:21
Show Gist options
  • Save RocketPuppy/2d3cc1ad57ef34ecb79cd2fe7245897d to your computer and use it in GitHub Desktop.
Save RocketPuppy/2d3cc1ad57ef34ecb79cd2fe7245897d to your computer and use it in GitHub Desktop.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { configureStore, createAction, createReducer } from "@reduxjs/toolkit";
import { Provider, connect } from "react-redux";
import * as O from "optics-ts";
import * as R from "redux-consumer-toolkit";
interface State {
counter: number;
}
const defaultState: State = { counter: 0 };
// Define starting point for state lenses
const stateO = O.optic<State>();
// Define trivial lens to focus the counter value
const counter = stateO.prop("counter");
const incrementAction = createAction<undefined>("increment");
// Use redux-consumer-toolkit to map over the state, modifying the counter using our lens
const incrementReducer = R.map(O.modify(counter)(x => x + 1), R.identity);
const reducer = createReducer(
defaultState,
builder =>
// Increment when we increment
builder.addCase(incrementAction, incrementReducer)
);
export type RootState = ReturnType<typeof reducer>;
const store = configureStore({ reducer });
const App = connect(
// This is ugly because of bad type inference. It should just be R.identity
(state: State) => R.identity<unknown, State>(state, null),
{ increment: incrementAction }
)((props: { counter: number, increment: typeof incrementAction }) => (
<div>
<span>{props.counter}</span>
<button onClick={() => props.increment()}>Increment</button>
</div>
));
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment