Ошибка реакции: «Отрисовано больше крючков, чем во время предыдущего отрисовки»

#javascript #reactjs

Вопрос:

У меня есть следующий компонент. Я использовал крючки react (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 />
        </>
    );
}
 

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

Комментарии:

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

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

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

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

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

Ответ №1:

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

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

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

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

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

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