djb
djb

Reputation: 1674

How to add an ID to react-table function?

I am trying to use react-table with useRowSelect, based on the tutorial. I have a REST app running at /associate but can't work out how to get the "selectedFlatRows[].original" data out of the table. Having two tables in one form also complicates things.

function App() {
  //...

  function handleSubmit(event) {
    event.preventDefault();
    const data = new FormData(event.target);

    fetch('/associate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: data,
    });
  }

  return (
    <form onSubmit={handleSubmit}>
      <Styles>
        <Table columns={tcsColumns} data={tcsList} />
        <Table columns={planColumns} data={planList} />
        <br />
        <button>Associate!</button>
      </Styles>
    </form>
  );
}

How do I access my two tables' data?

Upvotes: 4

Views: 6796

Answers (1)

Duc Hong
Duc Hong

Reputation: 1179

I've put together a quick modified version from your tutorial link. You can have a look here: https://codesandbox.io/s/tannerlinsleyreact-table-row-selection-h3z4h?fontsize=14&hidenavigation=1&theme=dark

Basically, what I did was:

  • Passing a function handler as onSelectedRows prop to each table. Inside each <Table /> , use useEffect hook to call this function whenever selectedFlatRows changes. (It seems like react-table utilize hook 100%, so I cannot find their document on using with class, but no worries, this still doesn't affect your app, as long as you use React 16.8+, you're fine)
function Table({ onSelectedRows, columns, data }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    ...,
    selectedFlatRows,
  } = useTable(
    {
      columns,
      data
    },
    useRowSelect
  );

  React.useEffect(() => {
    onSelectedRows(selectedFlatRows);
  }, [selectedFlatRows]);

  ...
}

From the parent scope, add a state to hold these selected rows. Then simply add a Button with onClick event handler to check the selected rows:

function App() {
  ...
  const [selectedRows, setSelectedData] = React.useState([]);
  const onSelectedRows = rows => {
    const mappedRows = rows.map(r => r.original);
    setSelectedData([...selectedRows, ...mappedRows]);
  };

  const onSubmitHandler = e => {
    e.preventDefault();
    console.log("submit: ", selectedRows);
  };

   return (
    <Styles>
      <button onClick={onSubmitHandler}>SUBMIT</button>
      <Table onSelectedRows={onSelectedRows} columns={columns} data={data} />
      <Table onSelectedRows={onSelectedRows} columns={columns2} data={data2} />
    </Styles>
  );
}

The takeaway point here is, you can pass a function to a component via prop, and use the values from component to handle on this parent scope. As what onSelectedRows did, here it receives a list of selected rows from table. I just do a naive solution to merge array and quick check. In real world scenario, you need to check for duplicate or added rows to skip it.

If your <App /> is a class-based component, It would look something like this: (notice on this.onSelectedRows, this.onSubmitHandler)

class App extends React.Component {
   state = {
      selectedRows: [],
   };

   const onSelectedRows = rows => {
    const mappedRows = rows.map(r => r.original);
    this.setState( prevState => {
       return {
        // your merged row array
       }
    })
  };

   const onSubmitHandler = e => {
     e.preventDefault();
     console.log("submit: ", selectedRows);
  };

   render() {
     return (
       <Styles>
         <button onClick={this.onSubmitHandler}>SUBMIT</button>
         <Table onSelectedRows={this.onSelectedRows} columns={this.columns} data={this.data} />
         <Table onSelectedRows={this.onSelectedRows} columns={this.columns2} data={this.data2} />
       </Styles>
     )
   }
}

You dont need a <form /> wrapper to be specifically calling submit as usual web browser. In your scenario, the data is quite simple so just a onClick event handler is enough.

Hope this help

Upvotes: 6

Related Questions