question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Autoprov

See original GitHub issue

Motivation

Ever since hooks and the context API released, I like to use useContext() for my global state similar to this:

// state.js
import React, {createContext, useContext, useState} from 'react';

const StateContext = createContext();

export const StateProvider = ({initialState, children}) =>(
  <StateContext.Provider value={useState(initialState)}>
    {children}
  </StateContext.Provider>
);

export const useStateValue = () => useContext(StateContext);

// App.js
import { StateProvider } from '../state';

const App = () => {
  const initialState = 1;
  
  return (
    <StateProvider initialState={initialState}>
        // App content ...
    </StateProvider>
  );
}

// Counter.js
import { useStateValue } from './state';

const Counter = () => {
  const [counter, setCount] = useStateValue();
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

While this example is written with useState, in reality I mostly use reducers. I typically generate these using Autodux. But using this global state pattern with useReducer also comes with a lot of boilerplate.

Solution / Proposal

Either as an addition to this package, or as a stand alone, we could write autoprov.

Here is how the API would be used:

state.js:

import { autoprov } from "autodux";

import {
  actions as counterActions,
  reducer as counter,
  getCounter
} from "./counter-reducer";
import {
  actions as toggleActions,
  reducer as toggle,
  getToggle
} from "./toggle-reducer";
import {
  actions as textActions,
  reducer as text,
  getText
} from "./text-reducer";

const { StateProvider, useBuildSlice } = autoprov({ counter, toggle, text });

const useCounter = () => {
  return useBuildSlice({
    selector: getCounter,
    alias: "clicks",
    actions: counterActions
  });
};

const useToggle = () => {
  return useBuildSlice({
    selector: getToggle,
    alias: "on",
    actions: toggleActions
  });
};

const useText = () => {
  return useBuildSlice({
    selector: getText,
    alias: "text",
    actions: textActions
  });
};

export { StateProvider, useCounter, useToggle, useText };

App.js:

import React, { Fragment } from "react";
import ReactDOM from "react-dom";

import "./styles.css";
import { useCounter, StateProvider, useToggle, useText } from "./state";

function Global() {
  const { text } = useText();
  const { clicks } = useCounter();
  return (
    <div>
      <div>Global Clicks: {clicks}</div>
      <div>Global Text: {text}</div>
    </div>
  );
}

const Counter = ({ clicks, onDecrement, onIncrement }) => (
  <Fragment>
    Clicks: <span className="clicks-count">{clicks}</span>&nbsp;
    <button className="click-dec-button" onClick={onDecrement}>
      Minus
    </button>
    <button className="click-inc-button" onClick={onIncrement}>
      Plus
    </button>
  </Fragment>
);

const Toggle = ({ on, onToggle }) => (
  <Fragment>
    The Switch is: <span className="toggle-state">{on ? "on" : "off"}</span>
    {on}&nbsp;
    <button className="toggle-button" onClick={onToggle}>
      Toggle
    </button>
  </Fragment>
);

function App() {
  const { clicks, decrement, increment } = useCounter();
  const { on, toggle } = useToggle();
  const { text, setText } = useText();
  return (
    <div className="App">
      <Counter
        clicks={clicks}
        onDecrement={decrement}
        onIncrement={increment}
      />
      <br />
      <Toggle on={on} onToggle={toggle} />
      <br />
      <input value={text} onChange={e => setText(e.target.value)} />
      <Global />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StateProvider>
    <App />
  </StateProvider>,
  rootElement
);

Here is a CodeSandBox with a whacky implementation.

What do you think? This would make it easy to use global state with context. I also like the functional composition nature of just being able to use useText() in a component. Obviously the name useBuildSlice should be changed 😄

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
janhesterscommented, Apr 3, 2019

@ericelliott Yup that’s correct! They both solve the same job. They just differ in the API. Autoprov would have a more useHook API, whereas React-Redux works with HOCs.

But maybe this pattern is bad, since React-Redux is going to have hooks soon anyways.

0reactions
ericelliottcommented, Apr 2, 2019

Basically my confusion is this:

If you put it in a Provider you can have global state.

Isn’t this what react-redux connect is for?

Read more comments on GitHub >

github_iconTop Results From Across the Web

gilbert-peterson/AutoProv - GitHub
AutoProv is a two phase script for recreating the provenance of a file from several temporal artifacts from digital forensics media.
Read more >
system auto-prov - Technical Documentation - Support
This command enables or disables auto provisioning. By default, auto provisioning is enabled—true. Auto provisioning allows an unprovisioned ...
Read more >
AutoProv: An Automated File Provenance Collection Tool
A file's provenance is a detailing of its origins and activities. There are tools available that are useful in maintaining the provenance of ......
Read more >
Zimbra auto-provisioining (autoprov) with multi-server ...
So now i have a one node Zimbra server that works smootly, this forum has been very helpful on every problem that i...
Read more >
CME Structure and Configurations - Check Point
See Supported Configuration Template parameters for parameter information. Closed To enable Software Blades in CLI on Security Gateways you plan to connect ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found