0

Codesandbox: https://codesandbox.io/s/magical-black-vp1r0?file=/src/dropdown-selector.js

I'm trying to build a very specific component and I'm not sure if its even possible or not. Please let me know.

Requirements:

  • SelectBox must be a CONTROLLED INPUT
  • DropdownSelector component can be consumed in any way possible (aka do not change App.js)
  • when clicking one of the options from the dropdown options, the value replaces the inputfield value

Reasons

  • I'm using react-intl and it only works for controlled inputs (translates instantly if value is controlled)
  • This component is a part of a monorepo, meaning the UI component should be versatile enough to be consumed in any way possible
  • The purpose of this component is a dropdown selector, meaning the user can type in a word and autocomplete options will dropdown for the user to click and "complete" their search

The dilemma is, if I want the component to be controlled, I must only use setVal method to change the state/value. For example, val can only be changed through setVal for a typical react input component like below:

const [val, setVal] = useState();
<input value={val} onChange={e => setVal(e.target.value)} />

However, in order for the dropdown option to replace the value of the input component, it must change the value state. But controlled components only have 1 way to change state and that's setVal in this case AND I can't change the way onChange consumes setVal because this is a UI component that should be able to be used in any versatile way.

So my question is: even though I'm sounding very hypocritical, is there a way to change that input component's value without using setVal?

Specific example in codesandbox above. Specific issue is in line 128 of DropdownSelector.js. Thank you very much in advance.

Jpark9061
  • 924
  • 3
  • 11
  • 26
  • 1
    Maybe I'm not understanding you or your use-case, but ***only*** the `value` attribute/prop of an input sets its value... meaning, it doesn't matter if a react `useState` hook value is the value, if a class-based component's state is the value, if the value is randomly generated, etc... Why do you think only *one* "thing" can set the value attribute of an input? You also claim you want this input to be "consumed in any way possible" but you appear to be tightly coupling its use to its implementation. Can you provide a better example of what you are trying to accomplish? – Drew Reese Oct 27 '20 at 00:23
  • @DrewReese But wouldn't that make the input value not controlled? Aren't controlled inputs defined by inputs with `value` set as `val` of `useState` and `onChange` triggers `setVal` of `useState`? – Jpark9061 Oct 27 '20 at 05:44
  • If a truthy value is passed to the `value` attribute of an input, it's a controlled input, simple as that. Anything can set the value used/passed to the input's `value` attribute. The `onChange` is *just* a callback function; it can do anything, including ***not*** updating any state anywhere. – Drew Reese Oct 27 '20 at 06:10
  • @DrewReese Oh my goodness really? Did not know that... what is a truthy value? none null and undefined? – Jpark9061 Oct 27 '20 at 06:23
  • Falsey values are `false`, `0`, `-0`, `0n`, `''`, `undefined`, `null`, and `NaN`, pretty much all other values are considered truthy values. [Truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) [Falsey](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) – Drew Reese Oct 27 '20 at 06:23

1 Answers1

0

In your codesandbox, you should either:

  1. Add labelAndValue to your useEffect dependencies, or, better:

  2. Move onSelect out of useEffect on line 59 and into onMouseDown.

helloitsjoe
  • 6,264
  • 3
  • 19
  • 32