1

I have a table being built dynamically by mapping over an array. Each item in the array gets a row. One of the columns in each of these rows is a select. I only want that column's content to show when a button in the same row's next column is clicked.

My plan was to add some sort of a toggle bool property to each object in my array, but then when I try to toggle it in my button's onclick, my eslint is complaining because I'm trying to modify a property of the parameter I sent into the function called by the onclick.

What is the appropriate way to do this?

Here's the code for the table:

<table>
  <tbody>
    {myArray.map(row => (
      <tr key={`test-${row.name}`}>
        <td>
          <div className="testClass">{row.id}</div>
        </td>
        <td>{row.name}</td>
        <td>
          <Select
            options={this.getOptions(row.id)}
            onSelect={this.onOptionSelect}
            placeholder="Select something"
          />
        </td>
        <td><button onClick={() => { changeStuff(row); }}>{ row.myToggle ? 'Save' : 'Change something' }</button></td>
      </tr>
    ))}
  </tbody>
</table>
6
  • Can you update exactly the eslint error? Commented Aug 23, 2017 at 9:02
  • 1
    can you share some code ? you probably need to handle the display of the column through a state flag Commented Aug 23, 2017 at 9:02
  • each row would have to have state to do a state flag, no? At this point, the rows do not have state. I don't want to show the dropdown for ALL rows, only the row for which the button is clicked. Commented Aug 23, 2017 at 9:05
  • @Firice - "Assignment to property of function parameter 'row'. (no-param-reaassign)" Commented Aug 23, 2017 at 9:07
  • 1
    @BenWalker. I have posted answer. Have a look!! Commented Aug 23, 2017 at 11:35

1 Answer 1

2

In click handler, you can update your array altogether to show/hide the select option.

Based on my understanding, I have tried creating below snippet. This is the way i could come up with, as per my understanding. I have maintained 'hidden' field in the array of objects. Instead of 'Select' I have used a simple button. You can change accordingly. Hope this helps.

const list = [
  {
    name: "Person 1",
    phone: "123-4567",
    id: 11,
    hidden:true
  },
  {
    name: "Person 2",
    phone: "123-4567",
    id: 12,
    hidden:true
  },
  {
    name: "Person 3",
    phone: "123-4567",
    id: 23,
    hidden:true
  },
  {
    name: "Person 4",
    phone: "123-4567",
    id: 34,
    hidden:true
  },
  {
    name: "Person 5",
    phone: "123-4567",
    id: 45,
    hidden:true
  }
];

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

    this.state = {
      list: list
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(item) {
    let updatedList = this.state.list.map(obj => {
       if(obj.id === item.id) {
         return Object.assign({}, obj, {
            hidden:!item.hidden
         });
       }
       return obj;
    });
    this.setState({
      list : updatedList
    });
  }

  render() {
    return (
      <div>
        <table>
          <tbody>
            {this.state.list.map(item =>
              <tr key={item.itemId}>
                <td>
                  {item.name}
                </td>
                <td>
                  {item.phone}
                </td>
                <td >
                  <button hidden={item.hidden}> Action </button>
                </td>
                <td>
                  <button
                    className="delete"
                    onClick={() => this.handleClick(item)}
                  >
                    Change
                  </button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("app"));
table td {
     font-size: 14px;
     font-weight: normal;
     padding: 10px;
     border: 1px solid #eee;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

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

1 Comment

still working on implementing. So far, it's looking good. Just want to make sure I've got it all working before accepting as answer.

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.