Reputation: 1674
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
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:
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