Skip to content

Instantly share code, notes, and snippets.

@cahnory cahnory/DataSelect.jsx
Last active Jun 21, 2016

Embed
What would you like to do?
DataSelect

Use any object as select option/value

Objects are compared with ===, object must be the same and not only deep equal

import React from 'react'
export function DataSelect({
children,
onData,
onChange,
value,
defaultValue,
...props,
}) {
const dataSet = DataSet()
// clone children with data props
const changeChildrenProps = (children) => {
return React.Children.map(children, changeChildProps)
}
// clone child with data props
const changeChildProps = (child) => {
if (child.type) {
const props = {
dataSet,
value: dataSet.getDataId(child.props.value),
defaultValue: dataSet.getDataId(child.props.defaultValue),
}
if ('option' === child.type) {
child = React.cloneElement(child, props)
} else if ('function' === typeof child.type) {
child = React.cloneElement(child, props, changeChildrenProps(child.props.children))
} else {
child = React.cloneElement(child, {}, changeChildrenProps(child.props.children))
}
}
return child
}
const handleChange = (e) => {
if (onData) {
onData(dataSet.getData(e.target.value))
}
if (onChange) {
onChange(e)
}
}
return (
<select
value={dataSet.getDataId(value)}
defaultValue={dataSet.getDataId(defaultValue)}
dataSet={dataSet}
{...props}
onChange={handleChange}
children={changeChildrenProps(children)} />
)
}
DataSelect.propTypes = {
onData: React.PropTypes.func
}
export default DataSelect
function DataSet() {
const datas = []
const dataSet = {
getDataId: (data) => {
if (undefined === data) {
return undefined
}
let key = datas.indexOf(data)
if (-1 === key) {
key = datas.length
datas.push(data)
}
return key
},
getData: (id) => {
return datas[id]
}
}
return dataSet
}
const data = [
{id: 1, name: 'foo'},
{id: 2, name: 'bar'},
]
export function Usage({value}) {
return (
<DataSelect value={value || data[0]} onData={obj => doSomething(obj)}>
{ data.map(obj => <option value={obj}>{obj.name}</option>) }
</ObjectSelect>
)
}
@lionelB

This comment has been minimized.

Copy link

commented Jun 21, 2016

does

<select
      value={dataSet.getDataId(value)}
      defaultValue={dataSet.getDataId(defaultValue)}
      dataSet={dataSet}
      {...props}
      onChange={handleChange}
      children={changeChildrenProps(children)} />

is the same as

<select
      value={dataSet.getDataId(value)}
      defaultValue={dataSet.getDataId(defaultValue)}
      dataSet={dataSet}
      {...props}
      onChange={handleChange}>
  {children => React.children.map(children, changeChildProp)}
</select>
@cahnory

This comment has been minimized.

Copy link
Owner Author

commented Jun 21, 2016

Yes, they are exactly the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.