scope-value-hook.js 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import { useCallback, useEffect, useState } from 'react'
  2. import _ from 'lodash'
  3. /**
  4. * Binds a property in an Angular scope making it accessible in a React
  5. * component. The interface is compatible with React.useState(), including
  6. * the option of passing a function to the setter.
  7. *
  8. * @param {string} path - dot '.' path of a property in `sourceScope`.
  9. * @param {object} $scope - Angular $scope containing the value to bind.
  10. * @returns {[any, function]} - Binded value and setter function tuple.
  11. */
  12. export default function useScopeValue(path, $scope, deep = false) {
  13. const [value, setValue] = useState(() => _.get($scope, path))
  14. useEffect(() => {
  15. return $scope.$watch(
  16. path,
  17. newValue => {
  18. setValue(newValue)
  19. },
  20. deep
  21. )
  22. }, [path, $scope, deep])
  23. const scopeSetter = useCallback(
  24. newValue => {
  25. setValue(val => {
  26. const actualNewValue = _.isFunction(newValue) ? newValue(val) : newValue
  27. $scope.$applyAsync(() => _.set($scope, path, actualNewValue))
  28. return actualNewValue
  29. })
  30. },
  31. [path, $scope]
  32. )
  33. return [value, scopeSetter]
  34. }