Состояние подъема с помощью крючков (из сопоставленного массива)

#reactjs #react-hooks #react-state-management

#reactjs #реагирующие крючки #реагирование-управление состоянием

Вопрос:

Я в замешательстве относительно того, как я должен вызывать события из дочернего компонента с помощью перехватов (или, скорее, компонентов без состояния). Может быть, я слишком много думаю. Или недостаточно! Я построил простой пример, иллюстрирующий мое замешательство.

Допустим, у нас есть родительский компонент с некоторыми данными

 import React, { useState } from "react";
import ReactDOM from "react-dom";

const Parent = () => {
  const data = [
    {
      thing: 1,
      info: "this is thing 1"
    },
    {
      thing: 2,
      info: "this is thing 1"
    },
    {
      thing: 3,
      info: "this is thing 3"
    }
  ];

  function handleClick(item) {
    console.log(item);
  }

  return (
    <div> 
    <h1> This is the Parent </h1> 
    <Child data={data} onShowClick={handleClick} /> 
    </div>
  )
};
 

И дочерние компоненты, созданные в результате сопоставления с данными

 const Child = (data, {onShowClick}) => {
  return (
    <ul> 
      { data.data.map(item => {return (
        <li key={item.thing}>{item.info}
        <button onClick={() => onShowClick}>Click</button>  
        </li>
      )})}
    </ul> 
  )
}
 

Если бы все это было найдено в одном и том же компоненте, я бы сделал что-то вроде

 onClick={() => handleClick(item)}
 

Но вы не можете передать аргумент с помощью prop.

 onClick={(item) => onShowClick}
// Or
onClick={onShowClick(item)}
 

Возможно, перехваты меня смущают. Приветствуется любое направление.

Ответ №1:

Это просто, приятель. проверьте приведенный ниже код. Я только что внес некоторые изменения в ваш код.

 const Parent = () => {
    const data = [
        {
            thing: 1,
            info: "this is thing 1"
        },
        {
            thing: 2,
            info: "this is thing 2"
        },
        {
            thing: 3,
            info: "this is thing 3"
        }
    ];

    const handleClick = (item) => {
        console.log(item);
    }

    return (
        <div>
            <h1> This is the Parent </h1>
            <Child data={data} onShowClick={handleClick} />
        </div>
    )
};

const Child = (props) => {
    return (
        <ul>
            {props.data.map(item => {
                return (
                    <li key={item.thing}>{item.info}
                        <button onClick={() => props.onShowClick(item)}>Click</button>
                    </li>
                )
            })}
        </ul>
    )
}
 

Надеюсь, это полезно.

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

1. Это самое близкое к ответу — у меня действительно были деструктурированные реквизиты в дочерней функции, но это работает, если я передаю только реквизиты дочерней функции со стрелкой. Я не знаю, понимаю ли я, почему это работает при передаче только реквизита, а не (data, {onShowClick}) Спасибо!

2. Вы только что научили меня, как перемещать состояние между различными компонентами. Спасибо!

Ответ №2:

Это не имеет никакого отношения к hooks .

Вы должны проверить документацию о том, как передавать аргументы обработчикам событий: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

Это пример из документации.

 <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
 

Но поскольку вам это не нужно e , вы просто собираетесь передать item

 {
  data.data.map(item => (
    <li key={item.thing}>{item.info}
      <button onClick={() => onShowClick(item)}>Click</button>
    </li>
  ))
}
 

Ответ №3:

Я думаю, вы хотите объединить 2.

 onClick={(item) => onShowClick(item)}
 

Вам также необходимо добавить this , когда вы отправляете функцию дочернему элементу или делаете ее константой вне родительского элемента, onShowClick={this.handleClick}

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

1. Не повезло. Также поиграли с размещением обработчика в дочерней функции, чтобы передать ей аргумент, но затем вы сталкиваетесь с той же проблемой, когда вы передаете аргумент элемента

2. Получаете ли вы товар в закрытии? Что произойдет, если вы попытаетесь onClick={(item) => { console.log('clicked: ', item); onShowClick(item):}} ?

3. Это возвращает нулевые значения и некоторые предупреждения «Это синтетическое событие повторно используется для повышения производительности

4. Я думаю, что использование «этого» действительно является сутью проблемы. В классах «это» имеет смысл, но при использовании хуков мы в основном используем функциональные компоненты без ключевого слова «this» для привязки вещей.

Ответ №4:

onClick={() => onShowClick} ошибка, onShowClick функция не вызывается.

Если необходимо использовать значение из области видимости, оно:

   { data.data.map(item => (
    <li key={item.thing}>{item.info}
    <button onClick={() => onShowClick(item)}>Click</button>  
    </li>
  ))}