Skip to content

Commit

Permalink
fix: clear ghost value in input reflection (#857)
Browse files Browse the repository at this point in the history
* fix: clear ghost value in input reflection

* test: do not preserve ghost value on input reflection

* refactor: add mapping for attribute names to reset value
  • Loading branch information
iamogbz authored Jul 4, 2023
1 parent bd86de7 commit 80bd0c5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/components/Element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ export function Element<T extends string>({
[ref, scrollLeft, scrollTop],
);

// For attributes that are not always updated when the prop is removed
React.useEffect(
/** Manually reset missing values */ () => {
const valueResetMap = { value: "" };
Object.entries(valueResetMap).forEach(([name, resetValue]) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (ref) (ref as any)[name] = (props as any)[name] ?? resetValue;
});
},
[ref, props],
);

return React.createElement(
tagName.toLowerCase(),
{ ...props, ref: setRef },
Expand Down
22 changes: 22 additions & 0 deletions src/components/__tests__/Element.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,26 @@ describe("Element", () => {
</span>
`);
});

it("does not preserve ghost value on input element", () => {
const domRef = React.createRef<HTMLInputElement>();
const initialValue = "initial value";
/*
* Warning: You provided a `value` prop to a form field without an `onChange` handler.
* This will render a read-only field. If the field should be mutable use `defaultValue`.
* Otherwise, set either `onChange` or `readOnly`.
*/
const { rerender } = render(
<Element domRef={domRef} tagName="input" value={initialValue} />,
);
expect(domRef.current?.value).toEqual(initialValue);
/*
* Warning: A component is changing a controlled input to be uncontrolled.
* This is likely caused by the value changing from a defined to undefined, which should not happen.
* Decide between using a controlled or uncontrolled input element for the lifetime of the component.
* More info: https://reactjs.org/link/controlled-components
*/
rerender(<Element domRef={domRef} tagName="input" />);
expect(domRef.current?.value).toHaveLength(0);
});
});

0 comments on commit 80bd0c5

Please sign in to comment.