【问题标题】:How to access history prop from a parent component using react?如何使用反应从父组件访问历史道具?
【发布时间】:2021-03-17 14:54:54
【问题描述】:

我有一个方法 showInfo 可以被两个组件 Child1 和 Child2 访问。

最初我在 Child1 组件中有 showInfo 方法,如下所示

const Child1 = ({history}: RouteComponentProps) => {
    type Item = {
        id: string,
        name: string,
        value: string,
    };

    const showInfo = (item: item) => {
        const id = item.id;
        const value = item.value;
        const handleRouteChange = () => {
            const path = value === 'value1' ? `/value1/?item=${itemId}` : `/value2/?item=${itemId}`; 
            history.push(path);
        }

       return (
           <Button onClick={handleRouteChange}> Info </Button>
       );
   }


   return (
       <SomeComponent 
           onDone = {({ item }) => {
               notify({
                   actions: showInfo(item)
               }) 
           }}
       />
   );

}

上面的代码有效。但现在我有另一个组件 child2 需要使用相同的方法 showInfo。

组件 child2 如下所示

const Child2 = () => {
   return (
       <Component 
           onDone = {({ item }) => {
               notify({
                   actions: showInfo(item)
               }) 
           }}
       />
   );

}

我没有在 Child2 组件中编写相同的方法 showInfo,而是将它放在不同的文件中,而 child1 和 child2 组件可以共享方法 showInfo。

下面是具有 showInfo 方法的名为 utils.tsx 的文件

 export const showInfo = (item: item) => {
        const id = item.id;
        const value = item.value;
        const handleRouteChange = () => {
            const path = value === 'value1' ? `/value1/?item=${itemId}` : 
            `/value2/?item=${itemId}`; 
            history.push(path); //error here push is not identified as no 
            //history passed
        }

       return (
           <Button onClick={handleRouteChange}> Info </Button>
       );
   }


   return (
       <SomeComponent 
           onDone = {({ item }) => {
               notify({
                   actions: showInfo(item)
               }) 
           }}
       />
   );

}

通过上述方法,我在 showInfo 方法中使用 history.push 时遇到错误。推送未定义。

这是因为这个文件 utils.tsx 中没有定义历史

现在的问题是如何从 child1 或 child2 组件传递历史记录。或者在这种情况下我可以访问历史记录的其他方式是什么。

有人可以帮我解决这个问题吗?谢谢。

编辑:

child1 和 child2 中的通知来自 useNotifications,如下所示

const useNotifications = () => {
    const [activeNotifications, setActiveNotifications] = React.useContext(
        NotificationsContext
    ); 
    const notify = React.useCallback(
         (notifications) => {
             const flatNotifications = flatten([notifications]);
             setActiveNotifications(activeNotifications => [
                 ...activeNotifications,
                 ...flatNotifications.map(notification => ({
                     id: notification.id,
                     ...notification,
                 });
             },
             [setActiveNotifications]
    )
    return notify;
}

【问题讨论】:

  • iirc 你可以从 "react-router-dom" 导入 {useHistory} 然后执行 const history = useHistory()

标签: javascript reactjs typescript


【解决方案1】:

虽然您可能会创建自定义挂钩,但您的函数会返回 JSX。有一个关于在自定义钩子here 中返回 JSX 的讨论。 IMO,这与其说是一个实用程序或自定义钩子场景,不如说它是一个可重用的组件。哪个好!

export const ShowInfo = (item: item) => { // capitalize

   const history = useHistory(); // use useHistory

   // ... the rest of your code

}

现在在 Child1 和 Child2 中:

return (
  <SomeComponent 
    onDone = {({ item }) => {
      notify({
        actions: <ShowHistory item={item} />
      }) 
    }}
  />
);

您可能需要根据 onDone 属性和 notify 函数调整一些代码,但这种模式为您提供了您正在寻找的可重用行为。

【讨论】:

  • 我收到无效的挂钩调用错误。钩子只能在函数组件的主体内部调用。我现在应该如何在 child1 和 child2 组件中调用 showInfo 方法。谢谢。
  • 该错误来自哪个组件?
  • child1 和 child2 组件。
  • 通知来自 const {notify} = useNotifications();
  • 我们能在那个钩子中看到更多的逻辑吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
  • 1970-01-01
  • 2018-01-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多