1

I'm using a material ui Table. One of the column has SelectField component, which is a dropdown with few items to choose from. Sample code here:

<TableBody
        displayRowCheckbox={this.state.showCheckboxes}
        deselectOnClickaway={this.state.deselectOnClickaway}
        showRowHover={this.state.showRowHover}
        stripedRows={this.state.stripedRows}
      >
        {tableData.map( (row, index) => (
          <TableRow key={index} selected={row.selected}>
            <TableRowColumn>{index}</TableRowColumn>
            <TableRowColumn>
                <SelectField key={index} value={row.clientId} onChange={this.handleRowChange}>
                {clientsDropdownData.map((row, index) =>(
                    <MenuItem key={row.val} value={row.val} primaryText={row.name} />

                ))}
                </SelectField>
            </TableRowColumn>
            <TableRowColumn>{row.name}</TableRowColumn>
            <TableRowColumn>{row.status}</TableRowColumn>
          </TableRow>
          ))}
      </TableBody>

Initial value of the dropdowns of all the rows are set properly based on clientId value from data supplied to the table. On change of selected row's dropdown, I want to change supplied data's clientId property. How can I achieve it? React is all about states. But how can I manage multiple and dynamic states?

This is what I have for onChange of SelectField:

handleRowChange = (event, index, rowValue) => {
      //this.setState({rowValue}); how to set state here?
      tableData[index]['clientId'] = rowValue; //this doesn't work. But this is what I want. I want to update tableData and also update the UI.
  }
2
  • Is 'tableData' part of your state? Are you using Flux or another pattern? Please provide more info. Commented Sep 21, 2016 at 10:56
  • 'tableData' is just a const on the same jsx file. const tableData = [ { name: 'John Smith', status: 'Employed', clientId: 1, selected: true, }, { name: 'Randal White', clientId: 2, status: 'Unemployed', }, ...... .... const clientsDropdownData = [{ val: 1,name: 'Abott'}, { val: 2, name: 'MSD' }, .. I'm not using flux. It's just react and material-ui. material-ui.com/#/components/table Commented Sep 21, 2016 at 11:05

1 Answer 1

0

You can use an attribute tableData in your state. When you want to update it (the table data and the Table view) you can just change your table data in the state with:

handleRowChange = (event, index, rowValue) => {
      let newTableData = this.state.tableData
      newTableData[index]['clientId'] = rowValue;
      this.setState({tableData: newTableData}); //New table set and view updated
  }

And use directly your state's table replacing:

{tableData.map( (row, index) => (

with

{this.state.tableData.map( (row, index) => (

This is why React's state is actually usfeul. You can put whatever you want there and, when you update it, the view will be re-rendered acordingly. If your state gets more complex you can use alternatives like Redux

Sign up to request clarification or add additional context in comments.

2 Comments

Ok. I have moved the data to state. handleRowChange seems more logical now. But I still have a problem. The index in handleRowChange is the SelectField's selected item's index and not the Table's selected row index. Hence I used another method of the table onTableRowSelection and set another state called selectedTableIndex. Works well now! Thanks :) I'm noob to React. I have a question though. If we have hundreds and thousands of rows and when we change just one row, does it make sense to update entire table's data? Doesn't it affect performance?
I don't really know a lot about performance issues with big object in React/Redux state because luckily I haven't dealt with them myself. But there are a lot of articles written about the topic and its relation with immutability. React provides an immutability helper. If you are worried about re-rendering, React will not just change the HTML when transitioning from one state to another,it finds the difference between them and updates accordingly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.