我想创建一个组件的新实例,然后在该组件中使用一个函数来添加一个新对象。什么都不适合我。这是我的代码:
包含列表的组件和添加新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不是函数。我尝试导出它,但由于它是函数中的一个函数,所以无法导出。如何实现以上目标?
您似乎误解了React的一些基础知识,您从未创建过这样的组件实例:
const eventDay = new EventDay();
而是渲染它们
<EventDay/>
和react为您创建实例。这就是说,当您想从父级调用EventDay
的方法时,您需要执行useImperativeHandle钩子。
挂钩只能在功能组件内部使用,而不能用作构造函数。标准答案是将状态处理移至包装组件(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
挂钩一起使用:
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
)