useReducer<TState, TAction> function

ReducerHook<TState, TAction> useReducer<TState, TAction>(
  1. TState reducer(
    1. TState state,
    2. TAction action
    ),
  2. TState initialState
)

Initializes state of a function component to initialState and creates a dispatch method.

Example:

Map<String, dynamic> reducer(
  Map<String, dynamic> state,
  Map<String, dynamic> action,
) {
  switch (action['type']) {
    case 'increment':
      return {...state, 'count': state['count'] + 1};
    case 'decrement':
      return {...state, 'count': state['count'] - 1};
    default:
      return state;
  }
}

final MyComponent = registerFunctionComponent((props) {
  final state = useReducer(reducer, {'count': 0});

  return div(children: [
    pEl('Count: \${state.state['count']}'),
    button(
      text: '+',
      onClick: () => state.dispatch({'type': 'increment'}),
    ),
    button(
      text: '-',
      onClick: () => state.dispatch({'type': 'decrement'}),
    ),
  ]);
});

Learn more: https://reactjs.org/docs/hooks-reference.html#usereducer

Implementation

ReducerHook<TState, TAction> useReducer<TState, TAction>(
  TState Function(TState state, TAction action) reducer,
  TState initialState,
) {
  JSAny? jsReducer(JSAny? jsState, JSAny? jsAction) {
    final dartState = jsState.dartify() as TState;
    final dartAction = jsAction.dartify() as TAction;
    final newState = reducer(dartState, dartAction);
    return (newState == null) ? null : (newState as Object).jsify();
  }

  final jsInitialState = (initialState == null)
      ? null
      : (initialState as Object).jsify();

  final result = _reactUseReducer(jsReducer.toJS, jsInitialState);
  final state = result[0].dartify() as TState;
  final dispatch = result[1]! as JSFunction;

  return ReducerHook._(state, (action) {
    dispatch.callAsFunction(null, action.jsify());
  });
}