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