React - 在表中处理多个SelectField

时间:2017-07-27 16:50:41

标签: reactjs dropdown

我试图在表格内以动态方式设置每个selectField的值。这是我的代码到目前为止,问题是当我更改一个selectField时它会更改所有这些并且我无法弄清楚如何使其按预期工作,只更新了所选的一个

import {
    Table,
    TableBody,
    TableHeader,
    TableHeaderColumn,
    TableRow,
    TableRowColumn,
} from 'material-ui/Table';

const months = [];
for (let i = 1; i <= 12; i++) {
    months.push(<MenuItem value={i} key={i} primaryText={`${i}`} />);
}
class Month extends Component {
    handleMonth = (value) => {
        this.setState({
            month: value
        });
    };
render() {
    return
    <Table selectable={false}>
        <TableHeader
            displaySelectAll={false}
            adjustForCheckbox={false}>
            <TableRow>
                <TableHeaderColumn>Meses</TableHeaderColumn>
            </TableRow>
        </TableHeader>
        <TableBody displayRowCheckbox={false} >
            {itemsMonths.map((row, index) => (
                <TableRow key={row.id}>
                    <TableRowColumn>
                        <SelectField
                            value={this.state.month}
                            onChange={this.handleMonth}>
                            {months}
                        </SelectField>
                    </TableRowColumn>
                </TableRow>
            ))}
        </TableBody>
    </Table>

}

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

原因是您通过单个状态值控制所有Selectfield,因此当您更改该状态值时,它正在所有Selectfield中进行更改。

<强>解决方案:

不是使用单个状态使用数组,而是使用每个Selectfield的值,而只更新特定值而不是所有值。

第1步:在构造函数中将月份定义为数组:

constructor(){
   super();
   this.state = {month: []}
}

第2步:为Selectefields使用特定值(每个字段一个值):

<SelectField
    value={this.state.month[index] || null}
    ....

第3步:在onChange函数中传递每个SelectField的索引以更新数组的特定值:

<SelectField
    ....
    onChange={this.handleMonth.bind(this, index)}>
    {months}
</SelectField>

第4步:更新onChange函数中的特定值:

handleMonth(index, value){
    let month = [...this.state.month];     //or this.state.month.slice(0)
    month[index] = value;
    this.setState({ month });
}

完整代码:

class Month extends Component {

    constructor(){
        super();
        this.state = {
            month: []
        }
    }

    handleMonth(index, value){
        let month = [...this.state.month];
        month[index] = value;
        this.setState({ month });
    }

    render() {
        return(
            <Table selectable={false}>
                ....

                <SelectField
                    value={this.state.month[index] || null}
                    onChange={this.handleMonth.bind(this, index)}>
                    {months}
                </SelectField>

                ....
            </Table>
        )
    }
}

答案 1 :(得分:1)

您只为所有行维护一个状态变量。这就是为什么每当您更改一个选择字段时,它都会反映到所有选择字段。因此,不要只维护一个状态变量,而是采用多个状态变量或数组。

import {
    Table,
    TableBody,
    TableHeader,
    TableHeaderColumn,
    TableRow,
    TableRowColumn,
} from 'material-ui/Table';

const months = [];
for (let i = 1; i <= 12; i++) {
    months.push(<MenuItem value={i} key={i} primaryText={`${i}`} />);
}
class Month extends Component {
    constructor(){
      this.state = { month: []}
    }
    handleMonth = (index) => {
       return (value) => {
          let tmp = [...this.state.month];
          tmp[index] = value;
          this.setState({
            month: tmp
          });
       }
    };
    render() {
     return
      <Table selectable={false}>
        <TableHeader
            displaySelectAll={false}
            adjustForCheckbox={false}>
            <TableRow>
                <TableHeaderColumn>Meses</TableHeaderColumn>
            </TableRow>
        </TableHeader>
        <TableBody displayRowCheckbox={false} >
            {itemsMonths.map((row, index) => (
                <TableRow key={row.id}>
                    <TableRowColumn>
                        <SelectField
                            value={this.state.month[index]}
                            onChange={this.handleMonth(index)}>
                            {months}
                        </SelectField>
                    </TableRowColumn>
                </TableRow>
            ))}
        </TableBody>
    </Table>

}