2017-03-17 91 views
1

厌倦了Firefox的丑陋选择并且无法对其进行设计。 我以为我会为了学习目的在React中做一个。反应:自定义选择元素

它似乎很容易实现,但我不知道如何做onChange与自定义组件,以及如何获取事件的价值。如果可能的话...

Select组件看起来是这样的:

type SelectProps = { 
    select: { 
    value: any 
    options: { 
     [k: string]: any 
    } 
    } 
} 

type SelectState = { 
    show: boolean 
} 

class Select extends Component<SelectProps, SelectState> { 
    constructor(props: SelectProps) { 
    super(props) 
    this.state = { 
     show: false 
    } 
    } 
    label = (v: any): string | undefined => { 
    for (var k in this.props.select.options) { 
     if (this.props.select.options[k] === v) return k 
    } 
    } 
    change = (i: number) => { 
    this.setState({ show: false }) 
    this.props.select.value = this.props.select.options[this.keys[i]] 
    } 
    display =() => { 
    this.setState({ show: !this.state.show }) 
    } 
    keys = Object.keys(this.props.select.options) 
    render() { 
    let { show } = this.state 
    let { options, value } = this.props.select 
    return (
     <div className='select'> 
     <button onClick={this.display}>{this.label(value)}</button> 
     {!show ? null : 
      <ul> 
      {this.keys.map((e: string, i: number) => (
       <li key={i} onClick={() => this.change(i)}>{e}</li>) 
      )} 
      </ul> 
     } 
     </div> 
    ) 
    } 
} 

它按预期工作。我可以设计它(hooray!)。

我从值参数中获取所选值。我想知道如果我能用onChange事件得到它吗?所以它表现得更像本地选择。

P.S.

这是它的(在触针)的造型,在情况下,它需要

.select 
    display: inline-block 
    position: relative 
    background: white 
    button 
    border: .1rem solid black 
    min-width: 4rem 
    min-height: 1.3rem 
    ul 
    position: absolute 
    top: 100% 
    border: .1rem solid black 
    border-top: 0 
    z-index: 100 
    width: 100% 
    background: inherit 
    li 
     text-align: center 
     &:hover 
     cursor: pointer 
     background: grey 

由于

回答

0

作为道具的一部分,传递一个更改回调。在change,调用回调并传递新的价值:

type SelectProps = { 
    select: { 
    onChange: any, // change callback 
    value: any, 
    options: { 
     [k: string]: any 
    } 
    } 
} 

... 
... 

change = (i: number) => { 
    this.setState({ show: false }) 
    this.props.select.value = this.props.select.options[this.keys[i]] 
    this.props.select.onChange(this.props.select.value); // call it 
} 

然后你就可以输出时,通过你的更改回调:

let s = { 
    value: '2', 
    options: { 
     '1' : 'one', 
     '2' : 'two' 
    }, 
    onChange : function(val){ 
     console.log("change to " + val); 
    } 
}; 

return (
    <Select select={s} /> 
);