reactjs / react.dev

The React documentation website
https://react.dev/
Creative Commons Attribution 4.0 International
11.08k stars 7.55k forks source link

Document useDispatcher pattern #1652

Open timlind opened 5 years ago

timlind commented 5 years ago

To mimic (easily testable) behaviour similar to redux thunk, a pattern such as useDispatcher can be used:

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

import "./styles.css";

function App(props) {
  var { state, click } = useStore();

  return (
    <div>
      <h1>State: {state}</h1>
      <button onClick={click}>Increment</button>
    </div>
  );
}

function useStore(props) {
  var [ state, dispatch ] = useReducer(reducer, []);
  var { click } = useDispatcher(dispatch, props);

  return {
    state,
    click
  };
}

function useDispatcher(dispatch, props) {
  function click() {
    dispatch({ type: 'click' });
    setTimeout(() => afterclick(), 2000);
  }

  function afterclick() {
    dispatch({ type: 'afterclick' });
  }

  return { click };
}

function reducer(state, { type, dispatch }) {
  switch (type) {
    case "click":
      return [...state, "click wait 2s..."];
    case "afterclick":
      return [...state, "....after"];
  }
}

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

Documenting this pattern may also help to ensure this is an optimised approach, or whether another solution is preferable.

redneckz commented 5 years ago

https://github.com/redneckz/react-dispatcher https://github.com/redneckz/eml-compliance-webapp