Передача функции в качестве prop приводит к ошибке?

#javascript #reactjs #typescript #types

#javascript #reactjs #typescript #типы

Вопрос:

Я передаю функцию (toggleFavoriteAction) моему компоненту RecipeListItem в качестве реквизита. Когда я нажимаю на кнопку для вызова функции, я получаю эту ошибку: TypeError: toggleFavoriteAction не является функцией. Но toggleFavoriteAction действительно является функцией.

введите описание изображения здесь

 // RecipeList
const toggleFavoriteAction = (recipe: RecipeConfig) => {
    return favorites.includes(recipe)
      ? dispatch(addToFavorites(recipe))
      : dispatch(removeFromFavorites(recipe));
  };

  const props = {
    toggleFavoriteAction,
    favorites,
  };

  return (
    <div>
      {recipes.results amp;amp;
        Array.isArray(recipes.results) amp;amp;
        recipes.results.map((data: RecipeConfig, key: number) => (
          <div key={key}>
            <RecipeListItem {...data} {...props} />
          </div>
        ))}
    </div>
  );
  
 // RecipeListItem
const RecipeListItem = (recipe: RecipeConfig, props: any): JSX.Element => {
  const { toggleFavoriteAction, favorites } = props;
...
......
  <button onClick={() => toggleFavoriteAction(recipe)}> // this button
     {favorites amp;amp; favorites.find((fav: any) => fav.id === recipe.id)
       ? 'Remove from fav'
       : 'Add to fav'}
  </button>
  

Комментарии:

1. Я думаю RecipeConfig , что это также части props объекта, и второго параметра не должно быть, вероятно props , в этом случае ваш будет неопределенным

2. Я вроде как уже пробовал это, я не смог сопоставить recipes.results таким образом.

3. Используете ли вы Redux ? Я думаю, проблема в том, как вы используете dispatch. Вы подключаете свое хранилище к компоненту? Определена ли отправка?

4. Да, я использую Redux. определена отправка (const dispatch=useDispatch()), и она подключена к хранилищу.

5. Можете ли вы войти toggleFavoriteAction в систему нажатием кнопки? Ошибка говорит, что это не функция, это дало бы нам подсказку, что это на самом деле.

Ответ №1:

Я думаю, проблема в том, как вы получаете доступ к свойствам

 // RecipeListItem
const RecipeListItem = (recipe: RecipeConfig, props: any): JSX.Element => { //here is wrong
  const { toggleFavoriteAction, favorites } = props;
...
......
  <button onClick={() => toggleFavoriteAction(recipe)}> // this button
     {favorites amp;amp; favorites.find((fav: any) => fav.id === recipe.id)
       ? 'Remove from fav'
       : 'Add to fav'}
  </button>
  

должно быть

 // RecipeListItem
const RecipeListItem = (props: any): JSX.Element => {
  
  const { toggleFavoriteAction, favorites, recipe } = props;
...
......
  <button onClick={() => toggleFavoriteAction(recipe)}> // this button
     {favorites amp;amp; favorites.find((fav: any) => fav.id === recipe.id)
       ? 'Remove from fav'
       : 'Add to fav'}
  </button>
  

оба {…data} и {…props}, которые вы передаете

  <RecipeListItem {...data} {...props} />

  

являются ли реквизиты

И вы можете получить доступ по первому аргументу компонента react

 const RecipeListItem = (props: any): JSX.Element => {
....
  

Комментарии:

1. При таком подходе мой рецепт теперь не определен.

2. поскольку вы распространяете data , поэтому вы не сможете получить к нему доступ, как recipe если бы вы этого хотели, вы можете уничтожить свой реквизит таким образом, чтобы все оставшиеся свойства переходили в объект recipe, т. Е. let { toggleFavoriteAction, favorites, ...recipe } = props

3. Ответ в порядке, но не передает данные: <RecipeListItem recipe={data} {...props} />