Skip to content

Commit 8e3a906

Browse files
authored
Explain Proxy in TableView (#4072)
Explain proxy usage in TableView
1 parent 0f953ca commit 8e3a906

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

packages/@react-aria/table/stories/example-resizing.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import {classNames} from '@react-spectrum/utils';
2727
import {FocusRing, useFocusRing} from '@react-aria/focus';
2828
import {mergeProps, useLayoutEffect, useResizeObserver} from '@react-aria/utils';
29-
import React, {useCallback, useState} from 'react';
29+
import React, {useCallback, useMemo, useState} from 'react';
3030
import styles from '@adobe/spectrum-css-temp/components/table/vars.css';
3131
import {useCheckbox} from '@react-aria/checkbox';
3232
import {useRef} from 'react';
@@ -69,6 +69,7 @@ export function Table(props) {
6969
state,
7070
ref
7171
);
72+
let layout = useMemo(() => ({...layoutState, tableState: state}), [layoutState, state]);
7273

7374
useLayoutEffect(() => {
7475
if (bodyRef && bodyRef.current) {
@@ -85,7 +86,7 @@ export function Table(props) {
8586
{[...headerRow.childNodes].map(column =>
8687
column.props.isSelectionCell
8788
? <TableSelectAllCell key={column.key} column={column} state={state} widths={widths} />
88-
: <TableColumnHeader key={column.key} column={column} state={state} widths={widths} layoutState={layoutState} onResizeStart={props.onResizeStart} onResize={props.onResize} onResizeEnd={props.onResizeEnd} />
89+
: <TableColumnHeader key={column.key} column={column} state={state} widths={widths} layout={layout} onResizeStart={props.onResizeStart} onResize={props.onResize} onResizeEnd={props.onResizeEnd} />
8990
)}
9091
</TableHeaderRow>
9192
))}
@@ -125,16 +126,15 @@ export function TableHeaderRow({item, state, children, className}) {
125126
</tr>
126127
);
127128
}
128-
function Resizer({column, state, layoutState, onResizeStart, onResize, onResizeEnd}) {
129+
function Resizer({column, layout, onResizeStart, onResize, onResizeEnd}) {
129130
let ref = useRef(null);
130131
let {resizerProps, inputProps} = useTableColumnResize({
131132
column,
132133
label: 'Resizer',
133134
onResizeStart,
134135
onResize,
135-
onResizeEnd,
136-
tableState: state
137-
} as AriaTableColumnResizeProps<any>, layoutState, ref);
136+
onResizeEnd
137+
} as AriaTableColumnResizeProps<any>, layout, ref);
138138

139139
return (
140140
<>
@@ -163,7 +163,7 @@ function Resizer({column, state, layoutState, onResizeStart, onResize, onResizeE
163163
</>
164164
);
165165
}
166-
export function TableColumnHeader({column, state, widths, layoutState, onResizeStart, onResize, onResizeEnd}) {
166+
export function TableColumnHeader({column, state, widths, layout, onResizeStart, onResize, onResizeEnd}) {
167167
let ref = useRef();
168168
let {columnHeaderProps} = useTableColumnHeader({node: column}, state, ref);
169169
let {isFocusVisible, focusProps} = useFocusRing();
@@ -197,7 +197,7 @@ export function TableColumnHeader({column, state, widths, layoutState, onResizeS
197197
</div>
198198
{
199199
column.props.allowsResizing &&
200-
<Resizer column={column} state={state} layoutState={layoutState} onResizeStart={onResizeStart} onResize={onResize} onResizeEnd={onResizeEnd} />
200+
<Resizer column={column} layout={layout} onResizeStart={onResizeStart} onResize={onResize} onResizeEnd={onResizeEnd} />
201201
}
202202
</div>
203203
</th>

packages/@react-spectrum/table/src/TableView.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
192192
// eslint-disable-next-line react-hooks/exhaustive-deps
193193
[props.overflowMode, scale, density, columnLayout]
194194
);
195+
196+
// Use a proxy so that a new object is created for each render so that alternate instances aren't affected by mutation.
197+
// This can be thought of as equivalent to `{…tableLayout, tableState: state}`, but works with classes as well.
195198
let layout = useMemo(() => {
196199
let proxy = new Proxy(tableLayout, {
197200
get(target, prop, receiver) {

0 commit comments

Comments
 (0)