如何从其父组件访问自定义react组件函数?

问题描述 投票:0回答:2

我想创建一个组件的新实例,然后在该组件中使用一个函数来添加一个新对象。什么都不适合我。这是我的代码:

包含列表的组件和添加新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不是函数。我尝试导出它,但由于它是函数中的一个函数,所以无法导出。如何实现以上目标?

javascript reactjs react-hooks react-component
2个回答
0
投票

您似乎误解了React的一些基础知识,您从未创建过这样的组件实例:

 const eventDay = new EventDay();

而是渲染它们

<EventDay/>

和react为您创建实例。这就是说,当您想从父级调用EventDay的方法时,您需要执行useImperativeHandle钩子。


0
投票

挂钩只能在功能组件内部使用,而不能用作构造函数。标准答案是将状态处理移至包装组件(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>

但是,如果必须从组件中获取功能,则可以将refuseImperativeHandle挂钩一起使用:

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
)
© www.soinside.com 2019 - 2024. All rights reserved.