Как перенести следующий хук на reasonml - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть следующий пользовательский хук

function useConstant(fn) {
  const ref = React.useRef()

  if (!ref.current) {
    ref.current = fn()
  }

  return ref.current
}

, и мне кажется, что портировать его на mindml довольно сложно, мне нужно дважды использовать приведение типа, какой идеальный способ?

external toAny: 'a => 'b = "%identity";
external toBool: 'a => bool = "%identity";

let useConstant = (fn: unit => 'a) => {
  let ref: React.Ref.t('a) = toAny(React.useRef());
  if (!toBool(React.Ref.current(ref))) {
    React.Ref.setCurrent(ref, fn());
  };
  React.Ref.current(ref);
};

1 Ответ

2 голосов
/ 01 мая 2020

Если я правильно понимаю назначение хука, то на самом деле это просто повторная реализация React.useMemo. Но ради обучения вот реализация, которая должна работать.

let useLazy = (fn: unit => 'a): 'a => {
  let ref = React.useRef(None);

  switch (React.Ref.current(ref)) {
  | Some(value) => value
  | None =>
    let value = fn();
    React.Ref.setCurrent(ref, Some(value));
    value;
  };
};

Используется тип опции , который специально разработан для подобных случаев. Если значения нет, мы представляем это значение option s None, а если есть значение, мы используем Some. Вместо использования if с семантически неясной концепцией истинности JavaScript мы сопоставим шаблон на option, используя switch, чтобы найти, что это None и значение необходимо вычислить или Some для получения значения.

Использование option и сопоставление с шаблоном действительно распространено в коде Reason, поэтому вам следует постараться понять, используя ссылки, приведенные выше, для получения более подробной информации. если нужно.

Обратите внимание, что вы могли бы также использовать Lazy для этого. Но это гораздо реже используется и, следовательно, гораздо менее полезно для изучения.

...