diff --git a/src/Spreadsheet.tsx b/src/Spreadsheet.tsx index 58bacc1a..216f6c61 100644 --- a/src/Spreadsheet.tsx +++ b/src/Spreadsheet.tsx @@ -283,24 +283,27 @@ const Spreadsheet = ( React.useEffect(() => { if ( props.selected && - prevSelectedPropRef.current && - !props.selected.equals(prevSelectedPropRef.current) + !state.selected.equals(props.selected) && + !prevSelectedPropRef.current?.equals(props.selected) ) { setSelection(props.selected); } prevSelectedPropRef.current = props.selected; - }, [props.selected, setSelection]); + }, [props.selected, setSelection, state.selected]); // Update data when props.data changes const prevDataPropRef = React.useRef | undefined>( props.data ); React.useEffect(() => { - if (props.data !== prevDataPropRef.current) { + if ( + props.data !== prevDataPropRef.current && + !Matrix.equals(props.data, state.model.data) + ) { setData(props.data); } prevDataPropRef.current = props.data; - }, [props.data, setData]); + }, [props.data, setData, state.model.data]); // Update createFormulaParser when props.createFormulaParser changes const prevCreateFormulaParserPropRef = React.useRef< diff --git a/src/matrix.ts b/src/matrix.ts index e275104f..61aff3ee 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -316,3 +316,36 @@ export function maxPoint(matrix: Matrix): Point.Point { const size = getSize(matrix); return { row: size.rows - 1, column: size.columns - 1 }; } + +export function equals(a: Matrix, b: Matrix): boolean { + if (a === b) { + return true; + } + + if (!a || !b) { + return false; + } + + const { rows: rowsA, columns: columnsA } = getSize(a); + const { rows: rowsB, columns: columnsB } = getSize(b); + + if (rowsA !== rowsB || columnsA !== columnsB) { + return false; + } + + for (const [point, valueA] of entries(a)) { + const valueB = get(point, b); + + if (valueA !== valueB) { + if (!valueA || !valueB) { + return false; + } + + if (JSON.stringify(valueA) !== JSON.stringify(valueB)) { + return false; + } + } + } + + return true; +}