首页 > 解决方案 > 离子反应组件重复渲染

问题描述

我无法在订单详细信息页面获取订单 ID,因为反应组件渲染多次。我已经尝试过以下解决方案,但它不起作用

https://codesandbox.io/s/solution-re-rendering-problem-tabs-6qskh?file=/src/pages/Tab1/Tab1.tsx

如何多次停止渲染

错误页面

错误图像

订单.tsx

import {
  IonButton,
  IonCol,
  IonContent,
  IonGrid,
  IonRow,
  IonText,
  IonList,
  IonItem,
  IonLabel,
} from "@ionic/react";
import React, { useState } from "react";
import "./Orders.css";
import axios from "axios";

export const Orders: React.FC = () => {
  console.log("order page");

  const [orders, setOrders] = useState([]);

  React.useEffect(() => {
    let isMounted = true;
    getOrders().then((data) => {
      if (isMounted) {
        setOrders(data.orderList.data);
      }
    });
    return () => {
      isMounted = false;
    };
  }, []);

  const getOrders = async () => {
    return axios({
      url: "http://example.com/api/orders",
      method: "get",
    }).then((response) => {
      return response.data;
    });
  };

  return (
    <IonContent>
      <div className="ion-padding">
        <h1>Orders</h1>
      </div>

      <IonList color="primary">
        {orders.map((order) => {
          return (
            <IonItem key={order.order_number}>
              {order.order_number}
              <IonButton
                routerLink={`/orderdetails/${order.order_code}`}
                color="primary"
                slot="end"
              >
                View
              </IonButton>
            </IonItem>
          );
        })}
      </IonList>
    </IonContent>
  );
};

export default React.memo(Orders);

应用程序.tsx

import React, { useState, useEffect, useContext } from "react";
import { Redirect, Route } from "react-router-dom";
import {
  IonApp,
  IonIcon,
  IonLabel,
  IonRouterOutlet,
  IonTabBar,
  IonTabButton,
  IonTabs,
  IonSplitPane,
  useIonRouter,
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { images, ellipse, square, triangle } from "ionicons/icons";
import Login from "./pages/Login";
import Menu from "./components/Menu";
import MainTabs from "./MainTabs";
import Profile from "./pages/Profile";
import { userContext } from "./userContext";
import Orders from "./pages/Orders";
import OrderDetails from "./pages/OrderDetails";
import { Plugins, Capacitor } from "@capacitor/core";

/* Core CSS required for Ionic components to work properly */
import "@ionic/react/css/core.css";

/* Basic CSS for apps built with Ionic */
import "@ionic/react/css/normalize.css";
import "@ionic/react/css/structure.css";
import "@ionic/react/css/typography.css";

/* Optional CSS utils that can be commented out */
import "@ionic/react/css/padding.css";
import "@ionic/react/css/float-elements.css";
import "@ionic/react/css/text-alignment.css";
import "@ionic/react/css/text-transformation.css";
import "@ionic/react/css/flex-utils.css";
import "@ionic/react/css/display.css";

const App: React.FC = () => {
  const { authValues, setAuthValues } = React.useContext(userContext);

  useEffect(() => {
    if (Capacitor.isNative) {
      Plugins.App.addListener("backButton", (e) => {
        if (
          window.location.pathname === "/tab1" ||
          window.location.pathname === "/login"
        ) {
          // Show A Confirm Box For User to exit app or not
          //let ans = window.confirm("Are you sure");
          //if (ans) {
          Plugins.App.exitApp();
          //}
        }
      });
    }
  }, []);

  return (
    <IonApp>
      {authValues.authenticated ? (
        <IonReactRouter>
          <IonSplitPane contentId="main">
            <Menu />
            <IonRouterOutlet id="main">
              <Route path="/profile" component={Profile} exact />
              <Route path="/orders" component={Orders} exact />
              <Route path="/orderdetails/:order_id" component={OrderDetails} exact />
              <MainTabs />
            </IonRouterOutlet>
          </IonSplitPane>
        </IonReactRouter>
      ) : (
        <IonReactRouter>
          <Route path="/login" component={Login} exact />
          <Redirect from="/" to="/login" exact />
        </IonReactRouter>
      )}
    </IonApp>
  );
};

export default App;

订单详情页面

import {
  IonButton,
  IonCol,
  IonContent,
  IonGrid,
  IonRow,
  IonText,
  IonList,
  IonItem,
  IonLabel,  
  IonFab, 
  IonFabButton, 
  IonIcon
} from "@ionic/react"
import React, { useState, useEffect, useRef } from "react";
import "./OrderDetails.css";
import axios from "axios";
import { useParams } from "react-router-dom";

axios.defaults.baseURL = process.env.REACT_APP_BE_URL;

export const OrderDetails: React.FC = () => {

  let { order_id } = useParams();

  console.log(order_id);

  console.log("order detail page");

  const [order, setOrder] = useState([])

  useEffect(() => {
    let isMounted = true
    getOrderDetails().then( data => {
      if (isMounted) {
        setOrder(data.orderDetails)
      }
    })
    return () => { isMounted = false }
  }, []);

  const getOrderDetails = async () => {
    return axios({
      url: 'http://example.com/api/order-details/10623',
      method: "get",
    }).then((response) => {
      return response.data;
    });
  };

  return (
    <IonContent>
      <div className="ion-padding">
        <h1>Order Details</h1>
      </div>

      <IonItem>
          <IonLabel>
            Order No.: {order.order_number}
          </IonLabel>
        </IonItem>

    </IonContent>
  )
}

export default React.memo(OrderDetails);

标签: reactjsionic-framework

解决方案


推荐阅读