Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F105175819
useControllableReducer.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 15, 04:55
Size
3 KB
Mime Type
text/x-java
Expires
Mon, Mar 17, 04:55 (2 d)
Engine
blob
Format
Raw Data
Handle
24938539
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
useControllableReducer.js
View Options
import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import areArraysEqual from '../utils/areArraysEqual';
/**
* Gets the current state. If the selectedValue is controlled,
* the `value` prop is the source of truth instead of the internal state.
*/
function getControlledState(internalState, props) {
if (props.value !== undefined) {
return _extends({}, internalState, {
selectedValue: props.value
});
}
return internalState;
}
function areOptionsEqual(option1, option2, optionComparer) {
if (option1 === option2) {
return true;
}
if (option1 === null || option2 === null) {
return false;
}
return optionComparer(option1, option2);
}
/**
* Triggers change event handlers when reducer returns changed state.
*/
function useStateChangeDetection(nextState, internalPreviousState, propsRef, lastActionRef) {
React.useEffect(() => {
if (!propsRef.current || lastActionRef.current === null) {
// Detect changes only if an action has been dispatched.
return;
}
const previousState = getControlledState(internalPreviousState, propsRef.current);
const {
multiple,
optionComparer
} = propsRef.current;
if (multiple) {
var _previousState$select;
const previousSelectedValues = (_previousState$select = previousState == null ? void 0 : previousState.selectedValue) != null ? _previousState$select : [];
const nextSelectedValues = nextState.selectedValue;
const onChange = propsRef.current.onChange;
if (!areArraysEqual(nextSelectedValues, previousSelectedValues, optionComparer)) {
onChange == null ? void 0 : onChange(lastActionRef.current.event, nextSelectedValues);
}
} else {
const previousSelectedValue = previousState == null ? void 0 : previousState.selectedValue;
const nextSelectedValue = nextState.selectedValue;
const onChange = propsRef.current.onChange;
if (!areOptionsEqual(nextSelectedValue, previousSelectedValue, optionComparer)) {
onChange == null ? void 0 : onChange(lastActionRef.current.event, nextSelectedValue);
}
}
// Fires the highlightChange event when reducer returns changed `highlightedValue`.
if (!areOptionsEqual(internalPreviousState.highlightedValue, nextState.highlightedValue, propsRef.current.optionComparer)) {
var _propsRef$current, _propsRef$current$onH;
(_propsRef$current = propsRef.current) == null ? void 0 : (_propsRef$current$onH = _propsRef$current.onHighlightChange) == null ? void 0 : _propsRef$current$onH.call(_propsRef$current, lastActionRef.current.event, nextState.highlightedValue);
}
lastActionRef.current = null;
}, [nextState.selectedValue, nextState.highlightedValue, internalPreviousState, propsRef, lastActionRef]);
}
export default function useControllableReducer(internalReducer, externalReducer, props) {
var _ref;
const {
value,
defaultValue
} = props;
const propsRef = React.useRef(props);
propsRef.current = props;
const actionRef = React.useRef(null);
const initialSelectedValue = (_ref = value === undefined ? defaultValue : value) != null ? _ref : props.multiple ? [] : null;
const initalState = {
highlightedValue: null,
selectedValue: initialSelectedValue
};
const combinedReducer = React.useCallback((state, action) => {
actionRef.current = action;
if (externalReducer) {
return externalReducer(getControlledState(state, propsRef.current), action);
}
return internalReducer(getControlledState(state, propsRef.current), action);
}, [externalReducer, internalReducer, propsRef]);
const [nextState, dispatch] = React.useReducer(combinedReducer, initalState);
const previousState = React.useRef(initalState);
React.useEffect(() => {
previousState.current = nextState;
}, [previousState, nextState]);
useStateChangeDetection(nextState, previousState.current, propsRef, actionRef);
return [getControlledState(nextState, propsRef.current), dispatch];
}
Event Timeline
Log In to Comment