Ошибка React: «Визуализировано больше хуков, чем во время предыдущего рендеринга»

avatar
Dhanushka S. Jayasinghe
9 августа 2021 в 06:13
415
1
1

У меня есть следующий компонент. Я использовал хуки реагирования (useHistory, useState) в своем компоненте.

export default function ClassTheoryDataTable() {

const dataSource = [
    {
        key: '1',
        date: '18.03.2021',
        subject: 'Revision',
        inst: 'HASHEL',
        edit: 'edit',
        delete: 'delete'
    }
];

    let history = useHistory();
    const [tableData, setTableData] = useState(dataSource);

    const handleRedirect = (data) => {
        history.push("/ClassTheoryDetails");
    };

    const handleDelete = (key) => {
        let dataSource1 = [...tableData];
        dataSource1 = dataSource1.filter((item) => item.key !== key);
        setTableData(dataSource1);
    }

    const columns = [
        {
            title: 'Date',
            dataIndex: 'date',
            key: 'date',
            render: (text, record) => (
                <a onClick={() => handleRedirect(record)} type="text">{text}</a>
            )
        },
        {
            title: 'Subject',
            dataIndex: 'subject',
            key: 'subject',
            editable: true
        },
        {
            title: 'Inst.',
            dataIndex: 'inst',
            key: 'inst',
            editable: true
        },
        {
            title: '',
            dataIndex: 'edit',
            key: 'edit',
            width: '50px',
            render: (text, record) => (
                <Space size="middle">
                    <EditOutlined style={{ color: '#1589FF', fontSize: '15px' }} />
                </Space>
            )
        },
        {
            title: '',
            dataIndex: 'delete',
            key: 'delete',
            width: '50px',
            render: (text, record) => (
                dataSource.length >= 1 ?
                    <Popconfirm title="Sure to delete ?" onConfirm={() => handleDelete(record.key)}>
                        <CloseCircleFilled style={{ color: 'red', fontSize: '15px' }} />
                    </Popconfirm>
                    : null
            )
        }
    ];
    return (
        <>
            <Table columns={columns} dataSource={tableData} pagination={false} bordered />
        </>
    );
}

По сути, я хочу удалить строку таблицы, щелкнув значок удаления в последнем столбце. Но при загрузке страницы я получаю сообщение об ошибке «Визуализировано больше крючков, чем во время предыдущего рендеринга». Я не знаю, как это исправить. Кто-нибудь может мне помочь?

Источник
Eldar B.
9 августа 2021 в 06:20
0

Обычно эта ошибка означает, что у вас есть хук, используемый условно. В React все хуки должны присутствовать на верхнем уровне функции и выполняться всегда, а не условно. Однако я не вижу никаких проблем с вашим кодом. У вас есть трассировка стека, которая ведет к определенной строке?

Eldar B.
9 августа 2021 в 06:23
0

Если трассировка стека просто ведет к этому файлу, я рекомендую закомментировать строки, чтобы найти проблемную. Я предполагаю, что это функция handleDelete или одна из ее строк.

Drew Reese
9 августа 2021 в 07:03
0

Вы уверены, что это код с проблемой? Это кажется достаточно простым, и я не вижу никаких ранних возвратов или других явных нарушений «Правил хуков». Есть ли у вас трассировка стека, сопровождающая ошибку, и набор шагов воспроизведения, чтобы мы могли лучше понять, что пользовательский интерфейс делал до этого момента?

Dhanushka S. Jayasinghe
9 августа 2021 в 07:03
0

@ЭльдарБ. да. было 27 стеков. Большинство стеков выглядят так: /node_modules/react-dom/cjs/react-dom.development.js. Но есть стек, показывающий эту строку. => new ClassTheoryDataTable /components/ClassTheoryDataTable.jsx:65, затем 65-я строка — это код useState ( const [tableData, setTableData] = useState(dataSource); )

Dhanushka S. Jayasinghe
9 августа 2021 в 07:21
0

@DrewReese На самом деле я новичок в Reactjs. Так что только у меня есть базовые знания. В моем проекте есть несколько компонентов. Я использовал хук useHistory для маршрутизации между компонентами. В этом компоненте есть таблица с фиктивными данными, и я хочу удалить строку таблицы, когда я нажимаю значок удаления в таблице. Без функции handleDelete код работает нормально. Поэтому я думаю, что ошибка должна быть здесь.

Drew Reese
9 августа 2021 в 07:33
0

Думаете, вы могли бы создать работающую демоверсию codeandbox, воспроизводящую эту проблему, которую мы сможем проверять и устранять в реальном времени? Скорее всего, вы обнаружите проблему, пытаясь свести ее к минимальному примеру. Если у вас есть этот код, размещенный в репозитории github, вы можете импортировать его в codeandbox.

Dhanushka S. Jayasinghe
9 августа 2021 в 08:48
0

@DrewReese Я еще не разместил свой проект на Github. Сейчас я постараюсь представить проект в codeandbox и дам вам знать, когда он будет готов.

Drew Reese
9 августа 2021 в 08:49
0

Конечно вещь. Для меня уже поздно, но просто пингуйте (@) меня снова здесь в комментарии, и я посмотрю, когда смогу.

Dhanushka S. Jayasinghe
13 августа 2021 в 08:36
0

@DrewReese это ссылка на демо-версию codeandbox ссылка , есть расширяемая таблица и значки удаления в таблице. Я хочу удалить строку, щелкнув эти значки. Но есть эта ошибка. Я прокомментировал строки кода, относящиеся к функции удаления.

Drew Reese
13 августа 2021 в 08:38
0

@DhanushkaS.Jayasinghe Спасибо. У меня сегодня опять поздно, но я более чем счастлив посмотреть утром.

Dhanushka S. Jayasinghe
13 августа 2021 в 08:46
0

@DrewReese Хорошо. нет проблем. Увидимся, когда сможешь. Спасибо, что действительно помогли мне.

Ответы (1)

avatar
Drew Reese
13 августа 2021 в 16:22
0

Ошибка выдается в коде компонента AntD, но проявляется только из-за того, как вы указали реквизиты таблицы.

Проблема заключается в вашем компоненте ClassTheory в expandRowRender, вы неправильно создаете экземпляр подтаблицы ClassTheoryDataTable.

const expandedRowRender = () => {
  const table = new ClassTheoryDataTable();
  return table;
};

Здесь вы вызываете функциональный компонент напрямую и возвращаете его, но это не то, как создаются экземпляры компонентов React. В React вы описываете пользовательский интерфейс с помощью JSX и передаете его в React, а React обрабатывает весь жизненный цикл компонента, от создания экземпляра, монтирования, повторного рендеринга и размонтирования.

Эта функция должна возвращать действительный JSX.

const expandedRowRender = () => {
  return <ClassTheoryDataTable />;
};