MCPcopy
hub / github.com/glideapps/glide-data-grid / useStateWithReactiveInput

Function useStateWithReactiveInput

packages/core/src/common/utils.tsx:219–257  ·  view source on GitHub ↗
(inputState: T)

Source from the content-addressed store, hash-verified

217// I'm sorry.
218const empty = Symbol();
219export function useStateWithReactiveInput<T>(inputState: T): [T, React.Dispatch<React.SetStateAction<T>>, () => void] {
220 // When [0] is not empty we will return it, [1] is always the last value we saw
221 const inputStateRef = React.useRef<[T | typeof empty, T]>([empty, inputState]);
222 if (inputStateRef.current[1] !== inputState) {
223 // it changed, we must use thee!
224 inputStateRef.current[0] = inputState;
225 }
226 inputStateRef.current[1] = inputState;
227
228 const [state, setState] = React.useState(inputState);
229 // crimes against humanity here
230 const [, forceRender] = React.useState<{} | undefined>();
231 const setStateOuter = React.useCallback<typeof setState>(nv => {
232 // this takes care of the case where the inputState was set, then setState gets called again but back to what
233 // the state was before the inputState changed. Since the useState effect wont trigger a render in this case
234 // we need to be very naughty and force it to see the change. Technically this may not be needed some chunk of
235 // the time (in fact most of it) but checking for it is likely to be more expensive than just over-doing it
236 const s = inputStateRef.current[0];
237 if (s !== empty) {
238 nv = typeof nv === "function" ? (nv as (pv: T) => T)(s) : nv;
239 if (nv === s) return; // they are setting it to what the inputState is anyway so we can just do nothing
240 }
241 if (s !== empty) forceRender({});
242 setState(pv => {
243 if (typeof nv === "function") {
244 return (nv as (pv: T) => T)(s === empty ? pv : s);
245 }
246 return nv;
247 });
248 inputStateRef.current[0] = empty;
249 }, []);
250
251 const onEmpty = React.useCallback(() => {
252 inputStateRef.current[0] = empty;
253 forceRender({});
254 }, []);
255
256 return [inputStateRef.current[0] === empty ? state : inputStateRef.current[0], setStateOuter, onEmpty];
257}
258
259export function makeAccessibilityStringForArray(arr: readonly string[]): string {
260 // this is basically just .join(", ") but checks to make sure it is not going to allocate

Callers 2

utils.test.tsFile · 0.85
DataEditorImplFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…