Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite rerender loop triggered with controlled Spreadsheet #410

Open
aioobe opened this issue Sep 11, 2024 · 4 comments
Open

Infinite rerender loop triggered with controlled Spreadsheet #410

aioobe opened this issue Sep 11, 2024 · 4 comments

Comments

@aioobe
Copy link

aioobe commented Sep 11, 2024

Reproducer:

yarn create vite spreadsheet-repro --template react-ts
yarn add scheduler react-spreadsheet
yarn
yarn dev

Then replace the code in App.tsx with the following:

  const [data, setData] = useState([
    [{ value: "Vanilla" }, { value: "Chocolate" }, { value: "" }],
    [{ value: "Strawberry" }, { value: "Cookies" }, { value: "" }],
  ]);

  const setDataWrapper = (data) => {
      console.log("setting data")
      setData(data)
  }      

  return (
    <Spreadsheet data={data} onChange={setDataWrapper} />
  )

Start editing cells and the console will be spammed with hundreds of rapid setting data lines. (It might take two or three edits, but it always happens consistently in both Firefox and Chrome.

Using react-spreadsheet 0.9.5 but have tried multiple versions ranging back to 0.7.0.

@dennis-meitner
Copy link

Experiencing the same issue!

@oskarscholander
Copy link

Same!

@ViniciusValler-Rapidsoft

Same issue here!

@danielgoodwin97
Copy link

Here's a temporary workaround which worked for me whilst we wait for a merge.

import _ from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
import ReactSpreadsheet from 'react-spreadsheet';

/**
 * A component for displaying a spreadsheet.
 * @param data
 * @param onChange
 * @returns {JSX.Element}
 * @constructor
 */
export default function Spreadsheet({ data, onChange }) {
    const previousData = useRef(data);
    const [spreadsheetData, setSpreadsheetData] = useState(data);

    /**
     * Handle the change of the spreadsheet data.
     * @type {(function(*): void)|*}
     */
    const handleSpreadsheetChange = useCallback(updatedData => {
        // If the data is different to the previous update, set the spreadsheet data.
        if (!_.isEqual(spreadsheetData, previousData.current)) {
            setSpreadsheetData(updatedData);

            // If there's a callback passed, then run it./
            if (onChange) {
                onChange(updatedData);
            }
        }

        // Update the previous data ref.
        previousData.current = updatedData;
    }, [spreadsheetData, previousData, onChange]);

    useEffect(() => {
        console.log('update');
    }, [spreadsheetData]);

    return <ReactSpreadsheet data={spreadsheetData} onChange={handleSpreadsheetChange} />;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants