Введено разбиение на страницы в моем приложении реакции. Работает нормально, но немного замедляется и не отвечает на запросы в приложении. Предупреждение о отключенном компоненте - PullRequest
0 голосов
/ 28 апреля 2020

Я представил новый пакет для моего приложения реагирования под названиемact-hooks-paginator (документы здесь ) и добавил его на несколько страниц, которые я хотел бы использовать для разбивки на страницы (например, список продуктов). Работает нормально, но после добавления приводит к нескольким непреднамеренным побочным эффектам.

  1. Вызывает некоторое замедление при щелчке по номерам страницы нумерации страниц.
  2. Некоторые функции навигации в приложении (с использованием «Связи» реакции-маршрутизатора-dom. Работает аналогично тегам привязки, но сохраняет сеанс для зарегистрированных пользователей) внутри нумерации страниц не всегда работает. Иногда мне приходится щелкать по нему несколько раз.
  3. Получение: «Предупреждение. Не удается выполнить обновление состояния React на неустановленном компоненте. Это не работает, но это указывает на утечку памяти в вашем приложении . Чтобы исправить, отмените все подписки и асинхронные задачи в функции очистки useEffect. " когда я покидаю страницу с нумерацией страниц.

Я почти уверен, что предупреждение о неустановленном компоненте - это root проблема здесь, но я не уверен, как справиться с этой ошибкой. Может кто-нибудь объяснить, что означает это предупреждение и что может его решить?

Ниже приведен один компонент, который у меня есть с нумерацией страниц.

productListPubli c. js

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import Paginator from "react-hooks-paginator";
import { CardColumns, Card, Row, Col, ListGroup, Form } from "react-bootstrap";
import axios from "axios";

function ProductListPublic(props) {
    const [isError, setIsError] = useState(false);
    const [products, setProducts] = useState([]);
    const [searchTerm, setSearchTerm] = useState("");
    const pageLimit = 9;
    const [offset, setOffset] = useState(0);
    const [currentPage, setCurrentPage] = useState(1);
    const [currentProducts, setCurrentProducts] = useState([]);

    const Product = props => (
        <Card>
            <Row>
                <Col md={{ span: 4 }}>
                    <Card.Title className="mt-4 text-center">
                        <Link to={`/products/list/${props.product._id}/`}>{props.product.name}</Link>
                    </Card.Title>
                </Col>
                <Col md={{ span: 8 }}>
                <ListGroup>
                    <ListGroup.Item className="text-truncate">{props.product.description}</ListGroup.Item>
                    {props.product.stock > 0 ? (
                        <ListGroup.Item>{props.product.stock} in stock</ListGroup.Item>
                    ) : (
                        <ListGroup.Item>Currently out of stock</ListGroup.Item>
                    )}
                </ListGroup>
                </Col>
            </Row>
        </Card>
    )

    useEffect(() => {
        axios.get("http://localhost:4000/products/")
        .then(res => {
            setProducts(res.data);
            setCurrentProducts(products.slice(offset, offset + pageLimit));
        }).catch(function(err) {
            setIsError(true);
        })
    }, [offset, products]);

    function productList() {
        if(searchTerm) {
            return products.filter(product => product.name.includes(searchTerm)).map((currentProduct, i) => {
                return <Product product={currentProduct} key={i} />;
            });
        } else {
            return currentProducts.map(function(products, i) {
                return <Product product={products} key={i} />;
            })
        }
    }

    return (
        <div className="text-center">
            <h2>Products List</h2>
            <Form>
                <Form.Row className="justify-content-sm-center">
                    <Form.Group as={Col} sm={{ span: 6 }}>
                        <Form.Label htmlFor="formSearch">Search Products</Form.Label>
                        <Form.Control
                                    controlid="formSearch"
                                    type="text"
                                    value={searchTerm}
                                    onChange={e => {
                                        setSearchTerm(e.target.value);
                                    }}
                                    placeholder="Product Name (case sensitive)"
                                    />
                    </Form.Group>
                </Form.Row>
            </Form>
            <CardColumns>
                { productList() }
                {!searchTerm &&
                    <Paginator
                        totalRecords={products.length}
                        pageLimit={pageLimit}
                        pageNeighbours={2}
                        setOffset={setOffset}
                        currentPage={currentPage}
                        setCurrentPage={setCurrentPage}
                    />
                }
            </CardColumns>
            { isError &&<p>Something went wrong with getting the products!</p> }
        </div>
    )
}

export default ProductListPublic;

1 Ответ

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

Проблемы, которые я нахожу в вашем использовании.

  • Используйте переменную isMount для отслеживания состояния монтирования элемента и возможности избежать обновления состояния реакции, когда он уже размонтирован. Это должно удалить предупреждение.

Окончательный код:

    useEffect(() => {
        let isMount = true
        axios.get("http://localhost:4000/products/")
        .then(res => {
            if (!isMount) return // If element has unmount, dont update the state
            setProducts(res.data);
            setCurrentProducts(products.slice(offset, offset + pageLimit));
        }).catch(function(err) {
            if (!isMount) return // If element has unmount, dont update the state
            setIsError(true);
        })
        return () => {
          isMount = false
        }
    }, [offset, products]);
...