function useReducer(reducer, initialState, init) {
	/** @type {import('./internal').ReducerHookState} */
	const hookState = getHookState(currentIndex++, 2);
	hookState._reducer = reducer;
	if (!hookState._component) {
		hookState._actions = [];
		hookState._value = [
			!init ? invokeOrReturn(undefined, initialState) : init(initialState),

			action => {
				hookState._actions.push(action);
				hookState._component.setState({});
			}
		];

		hookState._component = currentComponent;

		if (!currentComponent._hasScuFromHooks) {
			currentComponent._hasScuFromHooks = true;
			let prevScu = currentComponent.shouldComponentUpdate;

			currentComponent.shouldComponentUpdate = function (p, s, c) {
				return prevScu
					? prevScu.call(this, p, s, c) || hookState._actions.length
					: hookState._actions.length;
			};
		}
	}

	if (hookState._actions.length) {
		const initialValue = hookState._value[0];
		hookState._actions.some(action => {
			hookState._value[0] = hookState._reducer(hookState._value[0], action);
		});

		hookState._didUpdate = !ObjectIs(initialValue, hookState._value[0]);
		hookState._value = [hookState._value[0], hookState._value[1]];
		hookState._didExecute = true;
		hookState._actions = [];
	}

	return hookState._value;
}
@template {unknown} S
@template {unknown} A
@param {import('./index').Reducer<S, A>} reducer
@param {import('./index').Dispatch<import('./index').StateUpdater<S>>} initialState
@param {(initialState: any) => void} [init]
@returns {[ S, (state: S) => void ]}