Как получить доступ к пользовательской функции компонента реакции из его родительского компонента? - PullRequest
1 голос
/ 29 апреля 2020

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

Компонент, который содержит список и функцию для добавления нового eventCard

function EventDay (props) { 

   const [ events, setEvents ] = useState([{eventName: "first event"}]);

   function addEvent(eventCard) {
      setEvents( prevEvents => [...prevEvents, eventCard]);
   }

   return console.log(events);
}

export default EventDay;

компонент, который хочет получить доступ к функции addEvent

import EventDay from "./EventDay"

function App() {
   const eventDay = new EventDay();

   eventDay.addEvent({eventName: "New Event"});

}

Я получаю сообщение об ошибке addEvent не является функцией. Я пытался экспортировать его, но не могу, так как это функция внутри функции. Как я могу достичь вышеуказанного?

1 Ответ

1 голос
/ 29 апреля 2020

Крючки можно использовать только внутри функциональных компонентов, и их нельзя использовать в качестве конструкторов. Стандартный ответ будет состоять в том, чтобы переместить обработку состояния в компонент упаковки (App) и передать состояние EventDay:

const { useState, useCallback, useEffect } = React;

const EventDay = ({ events }) => events.map((o, i) => (<li key={i}>{o.eventName}</li>));

function App() {
  const [events, setEvents] = useState([{eventName: "first event"}]);
  
  const addEvent = useCallback(eventCard => setEvents(prevEvents => [...prevEvents, eventCard]), []);
  
  useEffect(() => {
    setTimeout(() => {
      addEvent({eventName: "new event"});
    }, 1000);
  }, [addEvent])
  
  return (
    <ul>
      <EventDay events={events} />
    </ul>
  );
}

ReactDOM.render(
  <App />,
  root
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

Однако, если вам нужно получить функцию от компонента, вы можете использовать ref с крючком useImperativeHandle:

const { forwardRef, useState, useImperativeHandle, useRef, useEffect } = React;

const EventDay = forwardRef((props, ref) => { 
  const [events, setEvents] = useState([{eventName: "first event"}]);

  useImperativeHandle(ref, () => ({
    addEvent(eventCard) {
      setEvents(prevEvents => [...prevEvents, eventCard]);
    }
  }));

  return events.map((o, i) => (<li key={i}>{o.eventName}</li>));
});

function App() {
  const eventRef = useRef();
  
  useEffect(() => {
    setTimeout(() => {
      eventRef.current.addEvent({eventName: "new event"});
    }, 1000);
  }, [])
  
  return (
    <ul>
      <EventDay ref={eventRef} />
    </ul>
  );
}

ReactDOM.render(
  <App />,
  root
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...