geist-ui: Input value can't be simply controlled by `value` prop

Bug report ๐Ÿž

Not sure if this is a bug or a design decision. In the scanbox link, keep input in either input, you can see the 's value is controlled by the value state while the is not.

Version & Environment

  • Version of browser chrome Version 83.0.4103.116 (Official Build) (64-bit)
  • Version of zeit-ui/react check sandbox

Expection

Just want to know if this is intentional.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (10 by maintainers)

Most upvoted comments

Very good discussion about the controlled component. In fact, I agree with you on some points.

First of all, Iโ€™d like to talk about why I provide (or design) internal state of the component: (Iโ€™m not arguing for point, just stating why) In most component libraries or official examples of React, it is a common practice to synchronize state externally, keeping a similar practice is to hope that most users can get a similar experience when using it.

Secondly, the Input component also provides some uncontrolled options:

  • If value is not set, no external synchronization is required (you mentioned that too). This means that values can be obtained at any time but state maintenance is not required.
  • Forwarded native Ref. Most of the time, users can skip synchronization and directly use Ref API to get values.
  • Provides initialValue options. This is useful if you want to skip synchronization and set the initial value.

Here Iโ€™ve created an example for Ref of Input.

Of course, even if the user can control Ref, the user cannot modify the internal state in other ways. The only way to do this is to add value and then change the value prop.


To be sure, now we have two problems that can be improved:

  1. Always need to synchronize state externally.
  2. Value of internal cannot be modified in an imperative API.

About synchronization of value:

Now we have some solutions to reduce the burden of this problem:

  • With useInput, you donโ€™t need to synchronize manually at all.
  • Do not set value. It may be useful in a few scenarios.
  • Do not set value, and use initialValue instead. (it canโ€™t cover all scenes.)
  • Do not set value, and use Ref to get value. (but the set action is invalid)

After pull request merged, we will add the following ways:

  • Do not set value, and use Ref to set value.

About imperative API:

Thanks to your advice, I optimized the way Input component works. Now when the value attribute is not set, the Input component is uncontrolled, In other words, you can use external ways to update, such as Ref or operate DOM API.

And I added an example of the imperative API to the document page of Input: #336