use-scope-value-setter-only.js 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import PropTypes from 'prop-types'
  2. import { useCallback, useState } from 'react'
  3. import { useIdeContext } from '../context/ide-context'
  4. import _ from 'lodash'
  5. /**
  6. * Similar to `useScopeValue`, but instead of creating a two-way binding, only
  7. * changes in react-> angular direction are propagated, with `value` remaining
  8. * local and independent of its value in the Angular scope.
  9. *
  10. * The interface is compatible with React.useState(), including
  11. * the option of passing a function to the setter.
  12. *
  13. * @param {string} path - dot '.' path of a property in the Angular scope.
  14. * @param {any} [defaultValue]
  15. * @returns {[any, function]} - value and setter function tuple.
  16. */
  17. export default function useScopeValueSetterOnly(path, defaultValue) {
  18. const { $scope } = useIdeContext({
  19. $scope: PropTypes.object.isRequired,
  20. })
  21. const [value, setValue] = useState(defaultValue)
  22. const scopeSetter = useCallback(
  23. newValue => {
  24. setValue(val => {
  25. const actualNewValue = _.isFunction(newValue) ? newValue(val) : newValue
  26. $scope.$applyAsync(() => _.set($scope, path, actualNewValue))
  27. return actualNewValue
  28. })
  29. },
  30. [path, $scope]
  31. )
  32. return [value, scopeSetter]
  33. }