按索引设置所选选项?

时间:2017-08-10 00:47:34

标签: reactjs

在React中,如何通过索引(<select>)设置所选选项(select.selectedIndex),而不是值?

e.g。我希望喜欢这两个选项选项“两个”:

const FancySelect = () => (
    <select selectedIndex={2}>
        <option>Zero</option>
        <option>One</option>
        <option>Two</option>
        <option>Three</option>
    </select>
)

你们还在试图作弊。我说没有设置<option value>。想象一下,我的选项列表如下所示:

export const options = [
    {value: Symbol(), label: "Zero"},
    {value: Symbol(), label: "One"},
    {value: Symbol(), label: "Two"},
    {value: Symbol(), label: "Three"},
    {value: Symbol(), label: "Zero"},
];

现在你无法options[0].value放入<option value>,因为它不是字符串。您也无法将label放入值中,因为它有重复项。

可以做的是找到选项的索引,例如

const index = options.findIndex(o => o.value === currentlySelectedValue);

现在我想使用index来设置当前选中的选项。在vanilla JS中,这就像mySelect.selectedIndex = index一样简单。

3 个答案:

答案 0 :(得分:1)

这不是你的反应,但你总是可以创建一个能够为你做到的组件:

class MySelect extends React.Component {
    render() {
        let value;
        if (this.props.selectedIndex && this.props.options.length > this.props.selectedIndex) {
            value = this.props.options[this.props.selectedIndex+1]
        }
        return (<select value={value}>
            {this.props.options.map((option, index) {
                return (
                    <option
                        key={index}
                        value={option}
                    >
                        {option}
                    </option>
                );
            })
            }
        </select>);
    }
}

====

<MySelect options={["Zefo", "One", "Two", "Three"]} selectedIndex="2" />

答案 1 :(得分:0)

创建一个选项对象数组。每个对象都有一个值和一个label属性。使用符号的.toString()方法设置值。使用selectedIndex prop从options数组中获取相应的值。

这是一个有效的sandbox

以下是代码示例:

const options = [
    { value: Symbol("Zero"), label: "Zero" },
    { value: Symbol("One"), label: "One" },
    { value: Symbol("Two"), label: "Two" },
    { value: Symbol("Three"), label: "Three" }
];

class MySelect extends React.Component {
    constructor( props ) {
        super( props );

        const { options, selectedIndex } = props;

        this.state = {
          value: options[ selectedIndex ].value.toString()
        }

      this.handleChange = this.handleChange.bind( this );
    }

    handleChange( e ) {
        this.setState({
            value: e.target.value
        });
    }

    render() {
        const { options } = this.props;
        const { value } = this.state;
        return (
            <select value={ value } onChange={ this.handleChange }>
                {
                    options.map(( option ) => (
                        <option
                            key={ option.label }
                            value={ option.value.toString() }
                        >
                            { option.label }
                        </option>
                    ))
                }
            </select>
        );
    }
}

<MySelect options={ options } selectedIndex={ 2 } />

答案 2 :(得分:0)

你可以这样包装<select>(Typescript / TSX):

import React, {SelectHTMLAttributes} from 'react';

export default class SelectByIndex extends React.PureComponent<SelectHTMLAttributes<HTMLSelectElement> & {selectedIndex: number|number[]}> {
    private select: HTMLSelectElement;

    componentDidMount() {
        this.refresh();
    }

    componentDidUpdate(prevProps) {
        if(prevProps.selectedIndex !== this.props.selectedIndex) {
            this.refresh();
        }
    }

    private refresh() {
        if(Array.isArray(this.props.selectedIndex)) {
            let indexes = new Set(this.props.selectedIndex);
            for(let i=0; i<this.select.options.length; ++i) {
                this.select.options[i].selected = indexes.has(i);
            }
        } else {
            this.select.selectedIndex = this.props.selectedIndex;
        }
    }

    private ref = n => {
        this.select = n;
    };

    render() {
        const {selectedIndex, ...props} = this.props;
        return <select {...props} ref={this.ref}/>;
    }
}