Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Select when passed a value as Prop errors with a suggestion to pass readOnly #27657

Closed
Biki-das opened this issue Nov 6, 2023 · 16 comments · Fixed by #27740
Closed

Bug: Select when passed a value as Prop errors with a suggestion to pass readOnly #27657

Biki-das opened this issue Nov 6, 2023 · 16 comments · Fixed by #27740
Assignees

Comments

@Biki-das
Copy link
Contributor

Biki-das commented Nov 6, 2023

Seems weird when we try to use a select component, and pass a value as a prop, it prompts with the error to either set onChange or readOnly.
the readOnly at the last seems misleading since the select component does not have a readOnly prop, unlike inputs which do have a readOnly attribute.

SELECT PROPS
https://react.dev/reference/react-dom/components/select

seems an easy fix would be to check if the mounted component is a select component and then conditionally just change the error message, though would need to add tests to support the same.

Screen.Recording.2023-11-06.at.9.27.49.AM.mov

cc @sophiebits

codesandbox link to tinker:- https://codesandbox.io/s/admiring-wright-9sctsn?file=/src/App.js

@Biki-das Biki-das added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Nov 6, 2023
@Biki-das
Copy link
Contributor Author

Biki-das commented Nov 6, 2023

I can work on this and make the error message correctly prompt.

@felipe-rodolfo
Copy link

export default function App() {
  const [selectedValue, setSelectedValue] = useState("fruits");

  return (
    <div className="App">
      <select value={selectedValue} onChange={(e) => setSelectedValue(e.target.value)}>
        <option value="Mango">Mango</option>
        <option value="Apple">Apple</option>
        <option value="Pears">Pears</option>
      </select>
      <input value="hello" readOnly={true} />
    </div>
  );
}

Does this work in your case?

@Biki-das
Copy link
Contributor Author

Biki-das commented Nov 7, 2023

export default function App() {
  const [selectedValue, setSelectedValue] = useState("fruits");

  return (
    <div className="App">
      <select value={selectedValue} onChange={(e) => setSelectedValue(e.target.value)}>
        <option value="Mango">Mango</option>
        <option value="Apple">Apple</option>
        <option value="Pears">Pears</option>
      </select>
      <input value="hello" readOnly={true} />
    </div>
  );
}

Does this work in your case?

@felipe-rodolfo the bug is not related to how i should use the Select component, the error message is the Problem since it says to pass a readOnly value to pass a prop as the option for the Select component which does not has the same and does not seem to be a good developer experience.

@Biki-das
Copy link
Contributor Author

Biki-das commented Nov 8, 2023

cc @hoxyq do lmk if this something valuable to fix!!

@hoxyq
Copy link
Contributor

hoxyq commented Nov 10, 2023

cc @hoxyq do lmk if this something valuable to fix!!

I think it is worth fixing, especially given the fact that https://react.dev/reference/react-dom/components/select doesn't list readOnly as an attribute.

seems an easy fix would be to check if the mounted component is a select component and then conditionally just change the error message, though would need to add tests to support the same.

I am not familiar with the code where this happens, but maybe its worth just implementing its own validation for select component.

@Biki-das
Copy link
Contributor Author

ok will look up we have holidays here till next week.
seems an easy fix would need to inspect the component and filter the message and add tests to support the same :-)

@Biki-das
Copy link
Contributor Author

@hoxyq can you change the status to confirmed if possible?

@hoxyq hoxyq added Component: DOM and removed Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug labels Nov 10, 2023
@Biki-das
Copy link
Contributor Author

Biki-das commented Nov 15, 2023

@hoxyq could you spare a few minutes to run the fixtures/packaging/babels-standalone/dev.html file ? for some reason ReactDOM.render() is not defined and on console.log(ReactDOM) it returns an empty Object.
am i doing something wrong?

if you are able to see hello world rendered could you just share the snippet and i can then test my changes.

@hoxyq
Copy link
Contributor

hoxyq commented Nov 15, 2023

@hoxyq could you spare a few minutes to run the fixtures/packaging/babels-standalone/dev.html file ? for some reason ReactDOM.render() is not defined and on console.log(ReactDOM) it returns an empty Object. am i doing something wrong?

if you are able to see hello world rendered could you just share the snippet and i can then test my changes.

Can confirm that it doesn't work for me also. Looks like a recent regression, but I don't have the time now to bisect the PR, which introduced this. I've validated that sourcemaps PRs are not related to it, so there is some commit prior to it that breaks this.

@Biki-das
Copy link
Contributor Author

Biki-das commented Nov 15, 2023

ok @hoxyq i understand appreciate your investigation, any other way i can test my changes if you know, i tried copying the node modules from the oss/experimental and putting the code of both react and react-dom inside the dummy react project of mine, but it is also not picking any changes.

@hoxyq
Copy link
Contributor

hoxyq commented Nov 15, 2023

ok @hoxyq i understand appreciate your investigation, any other way i can test my changes if you know, i tried copying the node modules from the oss/experimental and putting the code of both react and react-dom inside the dummy react project of mine, but it is also not picking any changes.

Jest tests, probably? Or try checking out on some older commit. I've tried main~100 and it works.

@Biki-das
Copy link
Contributor Author

ok @hoxyq i understand appreciate your investigation, any other way i can test my changes if you know, i tried copying the node modules from the oss/experimental and putting the code of both react and react-dom inside the dummy react project of mine, but it is also not picking any changes.

Jest tests, probably? Or try checking out on some older commit. I've tried main~100 and it works.

Thanks for the follow up, will try doing the same

@hoxyq
Copy link
Contributor

hoxyq commented Nov 17, 2023

@hoxyq could you spare a few minutes to run the fixtures/packaging/babels-standalone/dev.html file ? for some reason ReactDOM.render() is not defined and on console.log(ReactDOM) it returns an empty Object. am i doing something wrong?

if you are able to see hello world rendered could you just share the snippet and i can then test my changes.

Should be fixed with #27717.

@Biki-das
Copy link
Contributor Author

@hoxyq could you spare a few minutes to run the fixtures/packaging/babels-standalone/dev.html file ? for some reason ReactDOM.render() is not defined and on console.log(ReactDOM) it returns an empty Object. am i doing something wrong?
if you are able to see hello world rendered could you just share the snippet and i can then test my changes.

Should be fixed with #27717.

thanks @hoxyq , i have also found the file to change and return the appropriate error, once this is merged, i will take a pull and test the changes locally and add appropriate tests.

hoxyq pushed a commit that referenced this issue Dec 1, 2023
)

fix #27657 

added test in the `ReactDOMSELECT-test.js` to not allow regession to
happen in future.

After changes this is what the error message looks like


https://github.com/facebook/react/assets/72331432/53dcbe2a-70d2-43d2-a52d-a4fc389fdfbf
github-actions bot pushed a commit that referenced this issue Dec 1, 2023
)

fix #27657

added test in the `ReactDOMSELECT-test.js` to not allow regession to
happen in future.

After changes this is what the error message looks like

https://github.com/facebook/react/assets/72331432/53dcbe2a-70d2-43d2-a52d-a4fc389fdfbf

DiffTrain build for [5dd3596](5dd3596)
@vincerubinetti
Copy link

vincerubinetti commented Dec 4, 2023

Just ran into this and was very confused.

I think it is worth fixing, especially given the fact that https://react.dev/reference/react-dom/components/select doesn't list readOnly as an attribute.

To back this up, the TypeScript definitions also do not accept readOnly on a <select>, and MDN says it's not allowed (so I guess it's in the spec, though this doesn't make sense to me).


Here's the thing about just changing the error message though...

I'm using Zag.js for a single/multi-select component, and I have the following code to render a hidden input, which exists solely to provide a value to FormData:

<select
  {...api.hiddenSelectProps}
  value={multi ? api.value : api.value[0]}
>
  {options.map((option, index) => (
    <option key={index} value={option.id}>
      {option.text}
    </option>
  ))}
</select>

Zag already tracks the state via a statemachine, and the user is able to control the input via other controls that I didn't show. Therefore I really need a value and don't need an onChange. Adding disabled makes the error go away, but also omits the field from FormData.

So as far as I can see, to make the error go away, I have to provide onChange={() => null}. This feels a bit strange and dirty, so I think it's worth considering whether the rules you're checking here are truly air-tight. I think they usually are, and this is just a really weird edge case...

@hoxyq
Copy link
Contributor

hoxyq commented Dec 4, 2023

Just ran into this and was very confused.

I think it is worth fixing, especially given the fact that https://react.dev/reference/react-dom/components/select doesn't list readOnly as an attribute.

To back this up, the TypeScript definitions also do not accept readOnly on a <select>, and MDN says it's not allowed (so I guess it's in the spec, though this doesn't make sense to me).

Here's the thing about just changing the error message though...

I'm using Zag.js for a single/multi-select component, and I have the following code to render a hidden input, which exists solely to provide a value to FormData:

<select
  {...api.hiddenSelectProps}
  value={multi ? api.value : api.value[0]}
>
  {options.map((option, index) => (
    <option key={index} value={option.id}>
      {option.text}
    </option>
  ))}
</select>

Zag already tracks the state via a statemachine, and the user is able to control the input via other controls that I didn't show. Therefore I really need a value and don't need an onChange. Adding disabled makes the error go away, but also omits the field from FormData.

So as far as I can see, to make the error go away, I have to provide onChange={() => null}. This feels a bit strange and dirty, so I think it's worth considering whether the rules you're checking here are truly air-tight. I think they usually are, and this is just a really weird edge case...

IMHO, setting onChange to no-op is explicit and looks aligned with current react-dom APIs . If react-dom's select had hidden attribute, we could've also took it into account before printing an error.

EdisonVan pushed a commit to EdisonVan/react that referenced this issue Apr 15, 2024
…ebook#27740)

fix facebook#27657 

added test in the `ReactDOMSELECT-test.js` to not allow regession to
happen in future.

After changes this is what the error message looks like


https://github.com/facebook/react/assets/72331432/53dcbe2a-70d2-43d2-a52d-a4fc389fdfbf
bigfootjon pushed a commit that referenced this issue Apr 18, 2024
)

fix #27657

added test in the `ReactDOMSELECT-test.js` to not allow regession to
happen in future.

After changes this is what the error message looks like

https://github.com/facebook/react/assets/72331432/53dcbe2a-70d2-43d2-a52d-a4fc389fdfbf

DiffTrain build for commit 5dd3596.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants