Merge pull request #8103 from overleaf/ae-state-hooks-types

Add types to scope state hooks

GitOrigin-RevId: 61f903120b84a1770b1047953deb3a76ccfc50f0
This commit is contained in:
Alf Eaton 2022-05-25 08:57:57 +01:00 committed by Copybot
parent 852e27c080
commit 309742c37b
3 changed files with 32 additions and 27 deletions

View file

@ -5,6 +5,7 @@ import {
SetStateAction,
Dispatch,
} from 'react'
import _ from 'lodash'
import localStorage from '../../infrastructure/local-storage'
function usePersistedState<T>(
@ -17,10 +18,11 @@ function usePersistedState<T>(
})
const updateFunction = useCallback(
newValue => {
(newValue: SetStateAction<T>) => {
setValue(value => {
const actualNewValue =
typeof newValue === 'function' ? newValue(value) : newValue
const actualNewValue = _.isFunction(newValue)
? newValue(value)
: newValue
if (actualNewValue === defaultValue) {
localStorage.removeItem(key)

View file

@ -1,5 +1,9 @@
import PropTypes from 'prop-types'
import { useCallback, useState } from 'react'
import {
type Dispatch,
type SetStateAction,
useCallback,
useState,
} from 'react'
import { useIdeContext } from '../context/ide-context'
import _ from 'lodash'
@ -10,20 +14,17 @@ import _ from 'lodash'
*
* The interface is compatible with React.useState(), including
* the option of passing a function to the setter.
*
* @param {string} path - dot '.' path of a property in the Angular scope.
* @param {any} [defaultValue]
* @returns {[any, function]} - value and setter function tuple.
*/
export default function useScopeValueSetterOnly(path, defaultValue) {
const { $scope } = useIdeContext({
$scope: PropTypes.object.isRequired,
})
export default function useScopeValueSetterOnly<T = any>(
path: string, // dot '.' path of a property in the Angular scope.
defaultValue?: T
): [T, Dispatch<SetStateAction<T>>] {
const { $scope } = useIdeContext()
const [value, setValue] = useState(defaultValue)
const [value, setValue] = useState<T>(defaultValue)
const scopeSetter = useCallback(
newValue => {
(newValue: SetStateAction<T>) => {
setValue(val => {
const actualNewValue = _.isFunction(newValue) ? newValue(val) : newValue
$scope.$applyAsync(() => _.set($scope, path, actualNewValue))

View file

@ -1,5 +1,10 @@
import { useCallback, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import {
type Dispatch,
type SetStateAction,
useCallback,
useEffect,
useState,
} from 'react'
import _ from 'lodash'
import { useIdeContext } from '../context/ide-context'
@ -7,17 +12,14 @@ import { useIdeContext } from '../context/ide-context'
* Binds a property in an Angular scope making it accessible in a React
* component. The interface is compatible with React.useState(), including
* the option of passing a function to the setter.
*
* @param {string} path - dot '.' path of a property in the Angular scope.
* @param {boolean} deep
* @returns {[any, function]} - Binded value and setter function tuple.
*/
export default function useScopeValue(path, deep = false) {
const { $scope } = useIdeContext({
$scope: PropTypes.object.isRequired,
})
export default function useScopeValue<T = any>(
path: string, // dot '.' path of a property in the Angular scope
deep = false
): [T, Dispatch<SetStateAction<T>>] {
const { $scope } = useIdeContext()
const [value, setValue] = useState(() => _.get($scope, path))
const [value, setValue] = useState<T>(() => _.get($scope, path))
useEffect(() => {
return $scope.$watch(
@ -34,7 +36,7 @@ export default function useScopeValue(path, deep = false) {
}, [path, $scope, deep])
const scopeSetter = useCallback(
newValue => {
(newValue: SetStateAction<T>) => {
setValue(val => {
const actualNewValue = _.isFunction(newValue) ? newValue(val) : newValue
$scope.$applyAsync(() => _.set($scope, path, actualNewValue))