Как передать функцию через компонент с оператором распространения?

#reactjs #jsx

Вопрос:

Извините, новичок в react здесь. У меня возникли некоторые трудности при попытке передать информацию родительскому компоненту с помощью prop drill, чтобы установить значения в контекстном API, чтобы я мог передать информацию другому компоненту.

У меня есть вызываемый массив foodItem , который был передан из App.js к нижеприведенному компоненту с onGetFood функцией. Я создал еще одну промежуточную функцию тестирования, вызываемую getFoodItemInfo для перехода к следующему компоненту ChildFoodItem .

 //FoodList.jsx

function FoodItem ({foodItem}, {onGetFood}) {

    function getFoodItemInfo (food) {
        onGetFood();
        console.log("FOOOD");
    }

    return (
         <ChildFoodItem {...foodItem} **getFood={getFoodItemInfo}**/>
    );
}

//ChildFoodItem.jsx

    function ChildFoodItem (food, {getFood}) {
        
            getFood();
        
            return (
            <p className="flex-container">
                {/* First row - Macros */}
                <p className='task flex-child'>
                    <Button onClick={(e) => getFood()} style={{font: "bold"}} variant="link">{food.description} </Button>
                </p>
            </p>
            )
        }
 

Однако, когда я попытался перейти getFood к ChildFoodItem , я получаю, что функция не определена? Существует ли правило, по которому вы не можете выполнять детализацию функции, если используете оператор распространения?

Ответ №1:

Вы пытаетесь уничтожить параметр prop, который является первым параметром, который получает компонент. При указании нескольких параметров ( food, {getFood} ) реквизит попадает в food , и любой другой параметр будет неопределенным. Правильный синтаксис будет:

 function ChildFoodItem ({ getFood, ...food })
 

Это позволит извлечь getFood функцию из реквизитов и поместить остальные из них в food переменную.

Для получения более подробной информации об этом см. Раздел «Rest в деструктурировании объекта» в документации «Назначение деструктурирования».

Ответ №2:

Проблема

Реагирующие компоненты получают только один аргумент, props объект. При function ChildFoodItem (food, {getFood}) этом вы пытаетесь выполнить деструкцию getFood из неопределенного аргумента. Объект props, который вы назвали food .

Решение

Учитывая, что реквизиты передаются как:

 <ChildFoodItem {...foodItem} getFood={getFoodItemInfo} />
 

Затем getFood может быть явно деструктурирован, в то время как остальные food реквизиты передаются в переменную с именем food (или любым другим допустимым идентификатором).

 function ChildFoodItem ({ getFood, ...food }) {

  getFood();

  return (
    <p className="flex-container">
      {/* First row - Macros */}
      <p className='task flex-child'>
        <Button onClick={(e) => getFood()} style={{font: "bold"}} variant="link">{food.description} </Button>
      </p>
    </p>
  )
}