SolvedSemantic UI React 'event.target.value' are 'undefined' of 'onChange(event)' for 'Checkbox', 'Radio', and 'Dropdown'

Details

Version: "semantic-ui-react": "^0.54.2"

To reproduce the issue, here is the onChange() function:

function onChange(event) {
    console.log(`event.target.value: ${JSON.stringify(event.target.value)}`);
}

and use the following JSX for the testing:

const App = () => (
  <Container>
    <Divider hidden />
    <Header as='h1'>Checkbox</Header>
    <Segment>
      <Checkbox toggle label="Toggle" onChange={onChange}/>
      <Divider hidden />
      <Radio label="Radio" onChange={onChange} />
      <Divider hidden />
      <Input type="text" onChange={onChange} />
      <Divider hidden />
      <Dropdown selection options={options} placeholder='Dropdown' onChange={onChange} />
    </Segment>
  </Container>
)

Here is the sample code link for the test.

http://codepen.io/twang/pen/dpdowZ

Just open the Developer Tools, and check the Console, and then change each components' value.

For the <Input>, the event.target.value returns correct value of the <input ...>, however, for the <Checkbox>, <Radio> and <Dropdown>, the event.target.value are undefined.

11 Answers

✔️Accepted Answer

This is a known limitation. The event.target is a browser event property. However, many Semantic UI components, such as a Dropdown, Checkbox, and Radio do not work directly with native browser form controls such as input and select. They are built using stylized markup and custom internal state.

Because of this, there are no native browser events available for certain callbacks. This is why all change events in Semantic-UI-React provide the event first (when available) but also a second argument which contains the data you need. You should never have to access the native browser event for most tasks.

You can see examples of how to retrieve values from the second argument in the docs. Such as the Radio Group example.

Going to close this issue as this is not a bug. Feel free to open another issue if you feel any components are missing helpful data in the second argument and we can add more callback data.

Other Answers:

@twang2218 - to add to Levi's response, in the <Checkbox>, <Radio> and <Dropdown> components the second argument to onChange will be an object with name, value, and checked (if relevant). We're also considering just passing the whole props object back in addition to those keys (see #623).

@levithomason - for consistency, what do you think about returning { name, value } as the second argument to the onChange handler? Right now inside a Form component in my app I have:

handleDropdownChange (e, result) {
  const { name, value } = result
  // ...
}

handleInputChange (e) {
  const { name, value } = e.target
  // ...
}

which isn't ideal. I guess this would actually be addressed if we decided to pass all props back to handlers.

To keep things as simple and predictable as possible I think I'd like to push usage toward:

handleDropdownChange (e, data) {
  const { name, value } = data
  // ...
}

handleInputChange (e, data) {
  const { name, value } = data
  // ...
}

Where data may in fact be props per the issue you linked. We pass the event as a nicety really, just in case the user needs to handle an edge case. However it is inconsistent as noted.

More Issues: