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> | |
) | |
} |
Yes, they are exactly the same.
does
is the same as