Как создать функцию с фиксированным единственным аргументом, который игнорирует аргументы обратного вызова

#reactjs #functional-programming #lodash

#reactjs #функциональное программирование #Lodash

Вопрос:

У меня есть этот фрагмент кода:

 const App = () => {
  const [selectedMovie, setSelectedMovie] = useState(null);
  return (
    <>
      <AppHeader onSearchClick={() => setSelectedMovie(null)} />
      <AppBody selectedMovie={selectedMovie} onMovieSelect={setSelectedMovie} />
      <AppFooter />
    </>
  );
};
  

Недавно я провел рефакторинг в FP стиле. Чтобы это выглядело красиво, я бы хотел избежать вызова setSelectedMovie(null) в onSearchClick лямбде.

Чего я хотел бы достичь, так это передать функцию, которая будет игнорировать onSearchClick аргументы и будет вызываться с фиксированным null значением, что-то вроде этого:

 <AppHeader onSearchClick={setSelectedMovieCalledWithNullOnly} />
  

Возможно ли это, например, с lodash ?

Ответ №1:

Вы можете использовать _.wrap() для предоставления функции постоянного значения:

 const fn = x => console.log(x)
const alwaysNull = _.wrap(null, fn)

fn(5) // 5
alwaysNull(1243281) // null  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>  

Если могут быть другие параметры, и вы хотите ограничить функцию, вы также можете использовать _.ary() , чтобы установить arity функции (количество параметров, которые принимает функция) на 0 :

 const fn = (...args) => console.log(args)
const alwaysNull = _.ary(_.wrap(null, fn), 0)

fn(5) // 5
alwaysNull(1, 2) // null  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>  

И в вашем случае:

 const App = () => {
  const [selectedMovie, setSelectedMovie] = useState(null);

  const setSelectedMovieCalledWithNullOnly = _.wrap(setSelectedMovie, null);

  return (
    <>
      <AppHeader onSearchClick={setSelectedMovieCalledWithNullOnly)} />
      <AppBody selectedMovie={selectedMovie} onMovieSelect={setSelectedMovie} />
      <AppFooter />
    </>
  );
};