React JS Table Issue - javascript

I have a issue trying to fill a table with data that i recieve from a api.
I used axios to get the information, then i stored that into a state, and finally, i send to a projectsTable, that's a component to render a table with all the data.
The message that i recieved from the console is the follow "Uncaught Error: Objects are not valid as a React child (found: object with keys {---}). If you meant to render a collection of children, use an array instead."
I put some console logs to try to find the problem, and i saw that in the useEffect (when i read the information first), the setState doesn't execute.
I think that the problem could be in the render, because it's try to return the ProjectTable BEFORE the setProjects is execute, am i right?
Here I detach the code
export default function App() {
const columns = useMemo(
() => [
{
Header: 'Project',
columns: [
{
Header: 'Name',
accessor: 'name'
},
{
Header: 'details',
accessor: 'details'
}
]
}
const [projects, setProjects] = useState([]);
useEffect(() => {
axios
.get(URL_PROJECTS)
.then((response) => {
setProjects(response.data);
})
.catch((err) => console.log(err));
}, []);
return (
<div>
{projects.length !== 0 ? <ProjectTable data={projects} columns={columns} /> : <div />}
</div>
);
ProjectTable
export default function ProjectTable({ data, columns }) {
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()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
))}
</tr>
);
})}
</tbody>
</table>
);
}

Related

I am getting the Uncaught Error: Renderer Error when I try to render a table in react using react-table hook

I am quite new to development and just started with react. I have implemented a react-table and when rendered it in the App.js file but then I open the browser it does not render anything and gives an error in the consoleThis is the snapshot of the error
I also tried the Error Boundry method to see if it helps but it didn't
BasicTable.js
import { useTable } from "react-table";
import Mockdata from "./Mockdata.json";
import { Columns } from "./Columns";
export const BasicTable = () => {
const columns = useMemo(() => Columns,[]);
const data = useMemo(() => Mockdata,[]);
const tableInstance = useTable({ columns, data });
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
tableInstance;
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()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return <td {...cell.getCellProps()}>{cell.render('cell')}</td>;
})}
</tr>
);
})}
</tbody>
</table>
);
};
------------------------------------------------------
Mockdata.json
[
{
"id":"1a",
"name":"Prop1",
"defaultValue":"P1"
},
{
"id":"2a",
"name":"Prop2",
"defaultValue":"P2"
},
{
"id":"3a",
"name":"Prop3",
"defaultValue":"P3"
}
]
------------------------------------------------------------
Columns.js
export const Columns = [
{
Header:'Id',
accessor: 'id'
},
{
Header:'Name',
accessor: 'name'
},
{
Header:'DefaultValue',
accessor: 'defaultValue'
}
]
---------------------------------------------------------
App.js
import React from 'react';
import './App.css';
import { BasicTable } from './components/BasicTable';
function App() {
return (
<div className="App">
<BasicTable></BasicTable>
</div>
);
}
export default App;
include the Cell as capital c in which u rendered small c in return
that might help

How to show columns based on 2 selected dropdown react-table

[Link to Codesandbox of react-table
By default it will show all the available columns and when selecting 2 dropdown values it should show the 2 columns for comparison. So therefore it should display it in react table. I see there is an example of ticking checkboxes to show which column will be hidden, but in my case I want other way around when I have show the 2 columns when both dropdown is selected before showing it.
import { FC, useState } from "react";
import { useTable } from "react-table";
interface Column {
Header: string;
accessor: string;
id: Function | string | number;
}
interface TableProps {
columns: Array<any>;
data: Array<any>;
}
export const Table: FC<TableProps> = ({ columns, data }) => {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
allColumns,
} = useTable({
data,
columns,
});
const [valueOne, setValueOne] = useState("");
const [valueTwo, setValueTwo] = useState("");
const handleChangeOne = (e: any) => setValueOne(e.target.value);
const handleChangeTwo = (e: any) => setValueTwo(e.target.value);
return (
<>
<select value={valueOne} onChange={handleChangeOne}>
{allColumns.map((column) => (
<option value={column.id} {...column.getToggleHiddenProps()}>
{column.id}
</option>
))}
</select>
<select value={valueTwo} onChange={handleChangeTwo}>
{allColumns.map((column) => (
<option value={column.id} {...column.getToggleHiddenProps()}>
{column.id}
</option>
))}
</select>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
))}
</tr>
);
})}
</tbody>
</table>
</>
);
};
I would just use somthing like headerGroup.headers.filter((i)=> i === valueOne || i === valueTwo ).map(.....

react-table v7 dynamic columns and rows from a json data from an api

I am new to react. I have a json api which I need to display as a table in client side. I want to use react-table v7. My idea is:
Take the keys from the data as column Headers and Accessor
The json data are the rows
I have a table component, it takes the headers and data as props, kindly look below:
import React from 'react';
import { useTable } from 'react-table'
const Table = ({
headers,
items
}) => {
function getColumns() {
if (headers) {
return headers.map(key => {
return {
Header: key.toString(),
accessor: key.toString()
};
});
}}
const columns = React.useMemo(() => [
getColumns()
],
[]
)
const data = React.useMemo(() => [
items
], []
)
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, data })
return (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td
{...cell.getCellProps()}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
)
}
export default Table;
Then I have another component to make get request via axios and set columns and data from its response and import the Table component to pass the props define here, code below:
import React, { useEffect, useState } from 'react'
import Table from './Table'
import axios from 'axios'
export const STable = () => {
const [columns, setColumns] = useState([])
const [rows, setRows] = useState([])
const getData = () => {
axios.get("http://localhost:5001/")
.then(res => {
console.log(res.data)
setColumns({ columns: Object.keys(res.data[0]) })
setRows({ rows: res.data })
})
.catch(error => {
console.log(error)
})
}
useEffect(() => {
getData()
}, [] )
return (
<div>
<Table headers={columns} items={rows} />
</div>
)
}
export default Stable;
Finally the App component
import React from 'react';
import STable from './components/STable';
function App() {
return (
<div>
<STable/>
</div>
);
}
export default App;
However I get this error, see pic,
I do not know where I am doing wrong. I would appreciate any help.
You need to have id field in all columns with accessors. In your code you need to set id field for every inner column like that.
return headers.map(key => {
return {
id: key toString(),
Header: key.toString(),
accessor: key.toString()
};
});

Rendering React Table [v7] results in [object Object]

I'm new to Javascript so please bear with me. I'm attempting to render a table of data inside a div and I'm unable to do so. Basically I just want to replace the div in the html with the table div we've created.
I'm using react table v7 with webpack. The following code results in this being seen in the browser where the table should be.
Here is my code:
import { useTable } from 'react-table';
const ReactTable = require('react-table');
import React from 'react';
const tableData = [
{someColumn: 1, someOtherColumn: 'A'},
{someColumn: 2, someOtherColumn: 'B'}
]
const columnGenerator = (columnNames) => {
var updatedNames = columnNames.map(c => {
return {
Header: camelToTitle(c),
accessor: c
}
});
return [
{
Header: "Claims Data",
columns: updatedNames
},
]
};
const 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()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
})}
</tr>
);
})}
</tbody>
</table>
);
};
const table = <div>
<Table
columns={columnGenerator(Object.keys(tableData[0]))}
data={tableData}
/>
</div>
document.getElementById('claim-table').append(table);
[object Object] is just what is being rendered by converting that table object into a String. I would start by trying to use ReactDOM to mount that node instead of append:
import ReactDOM from 'react-dom'
...
ReactDOM.render(<Table
columns={columnGenerator(Object.keys(tableData[0]))}
data={tableData}
/>,
document.getElementById('claim-table')
)

Error at the moment sorting in Redux-React app

I have app wrote on pure React where I make request to server and get response - category list. This list I can sort by asc-desc when I click by title table id.I needed to remake small part of my React app to Redux.
But when I remake this part to redux I have error:
Cannot read property 'sortAscDesc' of undefined - in reducer.
Also error in Table.js in line:
<th className="th-id" onClick={() => dispatch(changeSortAscDesc())}>ID <small>{sortAscDesc}</small></th>
First in my question I'll write code that I remake to Redux
and below after _______________________________ I'll write small part my app which wrote on pure React(before remake to redux) and work well.
Wrote on REDUX:
filterList.js(action):
export const changeSortAscDesc = (prev) => ({
type: "SORT_ASC_DESC",
payload: prev
});
filterList.js(reducer):
const initialState = {
sortAscDesc: "asc",
};
export function filterList(state = initialState, action) {
switch (action.type) {
case "SORT_ASC_DESC": {
const { payload } = action;
return {
...state,
sortAscDesc: payload.sortAscDesc == 'asc' ? 'desc' : 'asc'
};
}
default:
return state;
}
}
Table.js:
export default (props) => {
const sortAscDesc = useSelector(state => state.filterListReducer.sortAscDesc);
const dispatch = useDispatch();
return (
<table>
<thead>
<tr>
<th></th>
<th onClick={() => dispatch(changeSortAscDesc())}>ID <small>{sortAscDesc}</small></th>
<th>TITLE</th>
</tr>
</thead>
<tbody className="table-body">
{props.dataAttribute.map(item => (
<tr key={item.id}>
<td>{item.id} </td>
<td>{item.title} </td>
</tr>
))}
</tbody>
</table>
);}
_______________________________________________________
Wrote on pure React (before remake to redux):
Home.js:
const Home = () => {
const [value, setValue] = useState({
listCategory: [],
sortAscDesc: "asc",
});
// Here useEffect and fetch function, but I dont write it, because it not related with my question
const changeSortAscDesc = () => {
setValue((prev) => ({
...prev,
sortAscDesc: prev.sortAscDesc == 'asc' ? 'desc' : 'asc'
}));
};
return (
<div>
<Table dataAttribute={value.listCategory}
changeSortAscDesc={changeSortAscDesc}
sortAscDesc={value.sortAscDesc}
/>
</div>
);
Table.js:
export default (props) => {
const sortAscDesc = useSelector(state => state.filterListReducer.sortAscDesc);
const dispatch = useDispatch();
return (
<table>
<thead>
<tr>
<th></th>
<th onClick={props.changeSortAscDesc}>ID <small>{props.sortAscDesc}</small></th>
<th>TITLE</th>
</tr>
</thead>
<tbody className="table-body">
{props.dataAttribute.map(item => (
<tr key={item.id}>
<td>{item.id} </td>
<td>{item.title} </td>
</tr>
))}
</tbody>
</table>
);}
You are not dispatching any payload with your action -
<th onClick={() => dispatch(changeSortAscDesc(dataThatNeedsToBePassed))}>ID <small>{sortAscDesc}</small></th> //pass data as parameter
EDIT- You can make it work in this way -
const initialState = {
sortAscDesc: "asc",
};
export function filterList(state = initialState, action) {
switch (action.type) {
case "SORT_ASC_DESC": {
const { payload } = action; // no need //
return {
...state,
sortAscDesc: state.sortAscDesc == 'asc' ? 'desc' : 'asc'
};
}
default:
return state;
}
}
And you can remove payload from your action -
export const changeSortAscDesc = () => ({
type: "SORT_ASC_DESC",
payload: prev// no need //
});

Categories

Resources