Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100890224
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
Mon, Feb 3, 16:10
Size
3 KB
Mime Type
text/x-java
Expires
Wed, Feb 5, 16:10 (2 d)
Engine
blob
Format
Raw Data
Handle
24051468
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