Reactの状態管理を一つのオブジェクトにまとめることでシンプルにする。しばらく使ってるけど便利。

CharlesStover/reactn: React, but with built-in global state management.

  • $ npm install reactn

ReactN devtool

  • $ npm install redux reactn-devtools ts
import addReactNDevTools from "reactn-devtools";
addReactNDevTools({ trace: true, traceLimit: 25 });

TypeScriptと組み合わせて使う場合、型チェックをきちんと働かせるためのコードが必要。 僕は初期値の設定と型の設定をまとめてやるようにしている。 initializeGlobalState.ts initializeGlobalState.ts

import { setGlobal } from 'reactn';
 
const INITIAL_GLOBAL_STATE = {
  logs: [] as string[],
}
 
export const initializeGlobalState = () => {
  setGlobal(INITIAL_GLOBAL_STATE);
}
 
type TYPE_GLOBAL_STATE = typeof INITIAL_GLOBAL_STATE
 
declare module 'reactn/default' {
  export interface State extends TYPE_GLOBAL_STATE { }
}

index.ts

initializeGlobalState()
ReactDOM.render(<App />, document.getElementById('root'));

Next.jsではwithInitを使う


some.tsx

import { useGlobal } from "reactn";
...
// in FC
  // rewrite like below
  // const [logs, setLogs] = useState([] as string[]);
  const [logs, setLogs] = useGlobal("logs");

some.tsx

somePromise.catch(()=>{
  // rewrite like below
  // setLogs([ERROR_ON_SERVER]);
  // setCanInput(false);
  setGlobal({ logs: [ERROR_ON_SERVER], canInput: false });
})

ts

import { useGlobal } from 'reactn';
 
export const PenButton = (props: any) => {
  const [pathCount] = useGlobal("pathCount");
  return <StyledIconButton aria-label="pen">
    <StyledBadge badgeContent={pathCount} color="primary">
      <PenSVGButton onClick={props.onClick} />
    </StyledBadge>
  </StyledIconButton>;
};

ts

import { getGlobal } from 'reactn';
 
  tool.onMouseDown = (event: any) => {
    setGlobal({ pathCount: getGlobal().pathCount + 1 })
 

---- ignore below, see ReactN+TypeScript

ts

export const INITIAL_STATE = {
  kanaBuffer: ""
};
export type TState = typeof INITIAL_STATE;

tsx

import { useGlobal, setGlobal } from 'reactn';
import { INITIAL_STATE, TState } from './INITIAL_STATE';

setGlobal(INITIAL_STATE);

const App: React.FC = () => {
  const [kanaBuffer] = useGlobal<TState>("kanaBuffer");
  return (
      <p>>{kanaBuffer}</p>
      <p>
        <input type="text" onKeyDown={keydownListener}></input>
      </p>
  );
}

ts

import { getGlobal, setGlobal } from 'reactn';
import { TState } from './INITIAL_STATE';
const kanaListener = (kana: string) => {
  const kanaBuffer = getGlobal<TState>().kanaBuffer;
  setGlobal({ kanaBuffer: kanaBuffer + kana });
}