Trying to include react-table in a basic app that takes input in a field, stores this in the ponents state when the field contents change, and then fetches data from Github on a button press.
Everything works fine until I add the line
const tableInstance = useTable({columns, data})
The page will load fine but the moment the input field changes (ie you type in it) the app crashes with the error:
Error: Maximum update depth exceeded. This can happen when a ponent repeatedly calls setState inside ponentWillUpdate or ponentDidUpdate. React limits the number of nested updates to prevent infinite loops.
The stack trace includes these snippets from the react-table library
hooks/useColumnVisibility.js
204 |
205 | useMountedLayoutEffect(() => {
206 | if (getAutoResetHiddenColumns()) {
> 207 | dispatch({ type: actions.resetHiddenColumns })
208 | ^ }
209 | }, [dispatch, columns])
210 |
and publicUtils.js:
153 |
154 | safeUseLayoutEffect(() => {
155 | if (mountedRef.current) {
> 156 | fn()
157 | ^ }
158 | mountedRef.current = true
159 | // eslint-disable-next-line
This is the code from my App.js file
import React, { useState } from 'react';
import './App.css';
import {useTable} from "react-table"
function App() {
const [data, setData] = useState([]);
const [keyword, setKeyword] = useState('');
const fetchData = () => {
const url = `=${keyword}`
fetch(url)
.then(response => response.json())
.then(responseData => {
setData(responseData.items);
});
}
const handleChange = (e) => {
setKeyword(e.target.value);
}
const columns = [{
Header: 'Name', //column header
accessor: 'full_name' //Value accessor
}, {
Header: 'URL',
accessor: 'html_url'
}, {
Header: 'Owner',
accessor: 'owner.login'
}]
const tableInstance = useTable({columns, data}) // line causing the problem
return (
<div className="App">
<input type="text" onChange={handleChange}/>
<button onClick={fetchData} value={keyword} >Fetch</button>
</div>
);
}
export default App;
Presumably, I've done something that causes the state to update every time the page is rendered thereby causing another render but I can't work out what it is. Thanks in advance for any help.
Trying to include react-table in a basic app that takes input in a field, stores this in the ponents state when the field contents change, and then fetches data from Github on a button press.
Everything works fine until I add the line
const tableInstance = useTable({columns, data})
The page will load fine but the moment the input field changes (ie you type in it) the app crashes with the error:
Error: Maximum update depth exceeded. This can happen when a ponent repeatedly calls setState inside ponentWillUpdate or ponentDidUpdate. React limits the number of nested updates to prevent infinite loops.
The stack trace includes these snippets from the react-table library
hooks/useColumnVisibility.js
204 |
205 | useMountedLayoutEffect(() => {
206 | if (getAutoResetHiddenColumns()) {
> 207 | dispatch({ type: actions.resetHiddenColumns })
208 | ^ }
209 | }, [dispatch, columns])
210 |
and publicUtils.js:
153 |
154 | safeUseLayoutEffect(() => {
155 | if (mountedRef.current) {
> 156 | fn()
157 | ^ }
158 | mountedRef.current = true
159 | // eslint-disable-next-line
This is the code from my App.js file
import React, { useState } from 'react';
import './App.css';
import {useTable} from "react-table"
function App() {
const [data, setData] = useState([]);
const [keyword, setKeyword] = useState('');
const fetchData = () => {
const url = `https://api.github./search/repositories?q=${keyword}`
fetch(url)
.then(response => response.json())
.then(responseData => {
setData(responseData.items);
});
}
const handleChange = (e) => {
setKeyword(e.target.value);
}
const columns = [{
Header: 'Name', //column header
accessor: 'full_name' //Value accessor
}, {
Header: 'URL',
accessor: 'html_url'
}, {
Header: 'Owner',
accessor: 'owner.login'
}]
const tableInstance = useTable({columns, data}) // line causing the problem
return (
<div className="App">
<input type="text" onChange={handleChange}/>
<button onClick={fetchData} value={keyword} >Fetch</button>
</div>
);
}
export default App;
Presumably, I've done something that causes the state to update every time the page is rendered thereby causing another render but I can't work out what it is. Thanks in advance for any help.
Share Improve this question asked Aug 23, 2020 at 17:01 Mike DaviesMike Davies 5546 silver badges19 bronze badges1 Answer
Reset to default 6Ok, so I fixed this by making a Table ponent that is then included in the App ponent DOM.
This is the updated code that fixes the issue
import React, { useState } from 'react';
import './App.css';
import {useTable} from "react-table"
function Table({columns, data}){
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({columns, data})
return (
<table {...getTableProps()}>
<thead>
{
headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{
headerGroup.headers.map( column => (
<th {...column.getHeaderProps()}>
{
column.render('Header')
}
</th>
))
}
</tr>
))
}
</thead>
<tbody {...getTableBodyProps()}>
{ // loop over the rows
rows.map(row => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{ // loop over the rows cells
row.cells.map(cell => (
<td {...cell.getCellProps()}>
{cell.render('Cell')}
</td>
))
}
</tr>
)
})
}
<tr>
<td></td>
</tr>
</tbody>
</table>
);
}
function App() {
const [data, setData] = useState([]);
const [keyword, setKeyword] = useState('');
const fetchData = () => {
const url = `https://api.github./search/repositories?q=${keyword}`
fetch(url)
.then(response => response.json())
.then(responseData => {
setData(responseData.items);
});
}
const handleChange = (e) => {
setKeyword(e.target.value);
}
const columns = [{
Header: 'Name', //column header
accessor: 'full_name' //Value accessor
}, {
Header: 'URL',
accessor: 'html_url'
}, {
Header: 'Owner',
accessor: 'owner.login'
}]
return (
<div className="App">
<input type="text" onChange={handleChange}/>
<button onClick={fetchData} value={keyword} >Fetch</button>
<Table
columns={columns}
data = {data}
/>
</div>
);
}
export default App;
The trouble is I don't really know why this works or what the crux of the issue was in the first place.