2017-03-17 68 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} /> 
);