React - Handle Multiple SelectField in table

不打扰是莪最后的温柔 提交于 2019-12-12 06:50:45

问题


Im trying to set the value of each selectField in a dynamic way inside a table. Here is my code so far, the problem is when i change one selectField it changes all of them and i cannot figure out how to make it to work as expected, only updated the one selected

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>

}

Can someone help me ?


回答1:


Reason is you are controlling all the Selectfield by a single state value, so when you are changing that state value, it is doing the changes in all the Selectfields.


Solution:

Instead of using a single state use array, on value of each Selectfield, and update only specific value not all the values.

Step 1: Define month as an array in constructor:

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

Step 2: Use specific value (one value for each field) for Selectefields:

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

Step 3: Pass index of each SelectField in onChange function to update the specific value of array:

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

Step 4: Update the specific value in onChange function:

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

Full Code:

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>
        )
    }
}



回答2:


You are maintaining only one state variable for all the rows. That is why whenever you change one select field, it reflect to all the select fields. So instead of maintaining only one state variable, take multiple state variables or an array.

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>

}


来源:https://stackoverflow.com/questions/45356700/react-handle-multiple-selectfield-in-table

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!