Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rex Dri
Rex Dri
Commits
ce477414
Verified
Commit
ce477414
authored
Apr 12, 2020
by
Florent Chehab
Browse files
fix(hooks): cleaned & optimized
* Created useOnBeforeComponentMount hook
parent
c1b57a4f
Changes
10
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/app/App.jsx
View file @
ce477414
/** General app JS entry
*/
import
React
,
{
useMemo
}
from
"
react
"
;
import
React
from
"
react
"
;
import
{
compose
}
from
"
recompose
"
;
import
{
Route
,
Switch
}
from
"
react-router-dom
"
;
import
FullScreenDialogServiceComponent
from
"
../services/FullScreenDialogServiceComponent
"
;
...
...
@@ -34,6 +34,7 @@ import CurrencyService from "../../services/data/CurrencyService";
import
LanguageService
from
"
../../services/data/LanguageService
"
;
import
FilterService
from
"
../../services/FilterService
"
;
import
AlertServiceComponent
from
"
../services/AlertServiceComponent
"
;
import
useOnBeforeComponentMount
from
"
../../hooks/useOnBeforeComponentMount
"
;
const
SERVICES_TO_INITIALIZE
=
[
UniversityService
,
...
...
@@ -43,17 +44,16 @@ const SERVICES_TO_INITIALIZE = [
LanguageService
,
FilterService
];
// import PageFiles from "../pages/PageFiles";
/**
* Main entry
*/
function
App
()
{
// Not using useEffect as it might not be called on first render exactly,
// Here we really need to have this stuff initialzed.
useMemo
(()
=>
{
useOnBeforeComponentMount
(()
=>
{
SERVICES_TO_INITIALIZE
.
forEach
(
service
=>
service
.
initialize
());
}
,
[]
);
});
return
(
<
div
...
...
frontend/src/components/services/AlertServiceComponent.jsx
View file @
ce477414
...
...
@@ -10,6 +10,8 @@ function AlertServiceComponent() {
useEffect
(()
=>
{
AlertService
.
setSetAlertProps
(
setAlertProps
);
return
()
=>
AlertService
.
setSetAlertProps
(()
=>
{});
},
[]);
const
handleClose
=
useCallback
(()
=>
setAlertProps
({
open
:
false
}),
[]);
...
...
frontend/src/hooks/useConstantState.js
deleted
100644 → 0
View file @
c1b57a4f
import
{
useState
}
from
"
react
"
;
/**
* Method to use a constant value. Can also be used with a function as initialValue to
* make sure something is ran directly.
* (useMemo might be rettrigered, useEffect with no dependencies seems to have some delay).
*
* @param initialValue
* @returns {unknown}
*/
function
useConstantState
(
initialValue
)
{
const
[
state
]
=
useState
(
initialValue
);
return
state
;
}
export
default
useConstantState
;
frontend/src/hooks/useEditor.jsx
View file @
ce477414
...
...
@@ -16,7 +16,7 @@ function useEditor(formInfo, onClose = () => {}) {
return
useCallback
(
modelData
=>
{
const
{
route
,
license
,
Form
,
formLevelErrors
}
=
formInfo
;
const
InternalEditor
=
()
=>
{
const
InternalEditor
=
React
.
memo
(
()
=>
{
const
{
saveData
,
clearSaveError
}
=
useEditorDispatch
(
route
);
const
{
...
...
@@ -40,7 +40,7 @@ function useEditor(formInfo, onClose = () => {}) {
onClose
=
{
onClose
}
/>
);
};
}
)
;
FullScreenDialogService
.
openDialog
(<
InternalEditor
/>);
},
[]);
...
...
frontend/src/hooks/useField.js
View file @
ce477414
import
{
useCallback
,
useContext
,
useMemo
,
useState
}
from
"
react
"
;
import
FormContext
from
"
../contexts/FormContext
"
;
import
CustomError
from
"
../components/common/CustomError
"
;
import
use
ConstantState
from
"
./useConstantState
"
;
import
use
OnBeforeComponentMount
from
"
./useOnBeforeComponentMount
"
;
/**
*
...
...
@@ -27,8 +27,7 @@ function useField(
const
[
allErrors
,
setAllErrors
]
=
useState
(
getError
(
valueInt
));
// Hack to make sure it is run NOW
useConstantState
(()
=>
{
useOnBeforeComponentMount
(()
=>
{
formManager
.
fieldSubscribe
(
fieldMapping
,
allErrors
,
setAllErrors
);
});
...
...
frontend/src/hooks/useOnBeforeComponentMount.js
0 → 100644
View file @
ce477414
import
{
useRef
}
from
"
react
"
;
/**
* Hook to make sure something is directly run and only ran during mount.
* (useMemo might be triggered again, useEffect with no dependencies seems to have some delay).
*
* @param {Function} execOnMount
* @returns {boolean} Has the method been executed?
*/
function
useOnBeforeComponentMount
(
execOnMount
)
{
const
ref
=
useRef
(
false
);
if
(
ref
.
current
===
false
)
{
execOnMount
();
ref
.
current
=
true
;
}
// Has been ran?
return
ref
.
current
;
}
export
default
useOnBeforeComponentMount
;
frontend/src/hooks/usePersistentState.js
View file @
ce477414
import
{
useCallback
,
useState
}
from
"
react
"
;
import
{
useCallback
,
useMemo
,
useState
}
from
"
react
"
;
import
{
getLatestRead
}
from
"
../utils/api/utils
"
;
import
use
ConstantState
from
"
./useConstantState
"
;
import
use
OnBeforeComponentMount
from
"
./useOnBeforeComponentMount
"
;
export
const
globalState
=
new
Map
();
...
...
@@ -35,30 +35,26 @@ export function getPersistedValue(key) {
*/
function
usePersistentState
(
key
,
initialValue
)
{
// initializing the global state if needed
// hack with useConstantState to make sure it is run NOW
useConstantState
(()
=>
{
useOnBeforeComponentMount
(()
=>
{
if
(
!
globalState
.
has
(
key
))
globalState
.
set
(
key
,
initialValue
);
});
const
[
st
oredValue
,
setStoredValu
e
]
=
useState
(()
=>
g
lobalState
.
get
(
key
));
const
[
st
ate
,
setStat
e
]
=
useState
(()
=>
g
etPersistedValue
(
key
));
const
setValue
=
useCallback
(
value
=>
{
const
currentGlobalValue
=
globalState
.
get
(
key
);
const
valueToStore
=
value
instanceof
Function
?
value
(
currentGlobalValue
)
:
value
;
const
setPersistentState
=
useCallback
(
value
=>
{
const
currentGlobalValue
=
getPersistedValue
(
key
);
const
valueToStore
=
value
instanceof
Function
?
value
(
currentGlobalValue
)
:
value
;
if
(
currentGlobalValue
!==
valueToStore
)
{
// Save state
globalState
.
set
(
key
,
valueToStore
);
setStoredValue
(
valueToStore
);
}
},
[
globalState
]
);
// Save global state
globalState
.
set
(
key
,
valueToStore
);
// save local state
setState
(
valueToStore
);
},
[]);
// Make sure to return the latest data
return
[
storedValue
,
setValu
e
];
return
useMemo
(()
=>
[
state
,
setPersistentState
],
[
stat
e
]
)
;
}
export
default
usePersistentState
;
frontend/src/hooks/useSharedReducer.js
View file @
ce477414
...
...
@@ -9,12 +9,13 @@ import useSharedState from "./useSharedState";
* @param {*} initialState - initial state value (if not already stored)
*/
function
useSharedReducer
(
key
,
reducer
,
initialState
)
{
const
[
savedState
,
setSavedState
]
=
useSharedState
(
key
,
initialState
);
const
[
sharedState
,
setSharedState
]
=
useSharedState
(
key
,
initialState
);
const
[
state
,
dispatch
]
=
useReducer
(
reducer
,
sharedState
);
const
[
state
,
dispatch
]
=
useReducer
(
reducer
,
savedState
);
useEffect
(()
=>
{
setS
av
edState
(
state
);
},
[
state
,
setS
av
edState
]);
setS
har
edState
(
state
);
},
[
state
,
setS
har
edState
]);
const
dispatchOut
=
useCallback
(
action
=>
{
// built-in support for action that take dispatch as argument
...
...
@@ -43,7 +44,7 @@ function useSharedReducer(key, reducer, initialState) {
},
[]);
// make sure to return the saved state to prevent bugs when directly accessing the saved data
return
useMemo
(()
=>
[
s
av
edState
,
dispatchOut
],
[
s
av
edState
,
dispatchOut
]);
return
useMemo
(()
=>
[
s
har
edState
,
dispatchOut
],
[
s
har
edState
,
dispatchOut
]);
}
export
default
useSharedReducer
;
frontend/src/hooks/useSharedState.js
View file @
ce477414
import
{
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
"
react
"
;
import
{
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"
react
"
;
import
usePersistentState
,
{
getPersistedValue
}
from
"
./usePersistentState
"
;
import
use
ConstantState
from
"
./useConstantState
"
;
import
use
OnBeforeComponentMount
from
"
./useOnBeforeComponentMount
"
;
/**
* @type {Map<string, Set.<function>>}
...
...
@@ -30,10 +30,9 @@ function useSharedState(key, valueIfNoPrevious) {
listenersByKey
.
get
(
key
).
delete
(
setState
);
}
};
},
[]);
},
[
listenersByKey
]);
// hack with useMemo to make sure it is run NOW
useMemo
(()
=>
{
useOnBeforeComponentMount
(()
=>
{
// Subscribe as a listener
if
(
!
listenersByKey
.
has
(
key
))
listenersByKey
.
set
(
key
,
new
Set
());
listenersByKey
.
get
(
key
).
add
(
setState
);
...
...
@@ -41,7 +40,7 @@ function useSharedState(key, valueIfNoPrevious) {
// small check to make sure the value is coherent
const
valueInStore
=
getPersistedValue
(
key
);
if
(
valueInStore
!==
state
)
setState
(
valueInStore
);
}
,
[]
);
});
const
setStateOut
=
useCallback
(
v
=>
{
...
...
@@ -53,10 +52,10 @@ function useSharedState(key, valueIfNoPrevious) {
f
(
v
);
});
},
[
listenersByKey
]
[
listenersByKey
,
setPersistedState
]
);
return
[
state
,
setStateOut
];
return
useMemo
(()
=>
[
state
,
setStateOut
]
,
[
state
,
setStateOut
])
;
}
export
default
useSharedState
;
frontend/src/hooks/wrappers/useSingleApiData.js
View file @
ce477414
...
...
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from "react";
import
{
apiDataIsUsable
,
getLatestRead
}
from
"
../../utils/api/utils
"
;
import
RequestParams
from
"
../../utils/api/RequestParams
"
;
import
{
useApiRead
}
from
"
./api
"
;
import
use
ConstantState
from
"
../useConstantState
"
;
import
use
OnBeforeComponentMount
from
"
../useOnBeforeComponentMount
"
;
/**
* Hook to provide access to the data from the backend stored in the global state.
...
...
@@ -11,7 +11,7 @@ import useConstantState from "../useConstantState";
* @param {"all"|"one"} variant - Is it a "all" or a "one" (GET all or GET one object)
* @param {RequestParams} [initialParams] - RequestParams for the first request.
* @returns {{
hasError: Boolean,
isLoading:
B
oolean,
latestData: any, data:
an
y
, setParams:
function
}}
* @returns {{isLoading:
b
oolean,
data: ({}|Function), latestData: *, hasError: boole
an, setParams:
React.Dispatch<React.SetStateAction<RequestParams>>
}}
*/
function
useSingleApiData
(
routeName
,
...
...
@@ -30,8 +30,7 @@ function useSingleApiData(
*/
// Initial load
// hack to make sure it is run NOW
useConstantState
(()
=>
{
useOnBeforeComponentMount
(()
=>
{
if
(
!
apiDataIsUsable
(
data
))
performRead
(
params
);
});
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment