React-table Select All Select Box - javascript

https://codesandbox.io/s/8x331yomp0
I'm trying to create a select all checkbox in my table. When I click the header checkbox, I want the other checkboxes to populate, as well.
I'm trying to do this with a selectAlll state value, but for whatever reason, this keeps coming back false the first time, so it is always opposite of what the value should be. Any chance someone knows what is wrong? I put the code sandbox up at the top, but here is my table code:
import React, { Component } from "react";
import $ from "jquery";
import ReactTable from "react-table";
import "react-table/react-table.css";
const style = {
container: {
position: "relative"
},
refresh: {
cursor: "pointer",
width: "75px"
}
};
class KKTable extends Component {
constructor() {
super();
this.state = {
loading: true,
timestamp: "",
selectAll: false,
data: [],
checked: []
};
this.handleChange = this.handleChange.bind(this);
}
handleChange = () => {
var selectAll = !this.state.selectAll;
this.setState({ selectAll: selectAll });
var checkedCopy = [];
this.state.data.forEach(function(e, index) {
checkedCopy.push(selectAll);
});
};
componentDidMount() {
const data2 = [
{ one: "hi0", two: "two0", three: "three0" },
{ one: "hi1", two: "two1", three: "three1" },
{ one: "hi2", two: "two2", three: "three2" },
{ one: "hi3", two: "two3", three: "three3" },
{ one: "hi4", two: "two4", three: "three4" },
{ one: "hi5", two: "two5", three: "three5" },
{ one: "hi6", two: "two6", three: "three6" },
{ one: "hi7", two: "two7", three: "three7" },
{ one: "hi8", two: "two8", three: "three8" }
];
var checkedCopy = [];
var selectAll = this.state.selectAll;
data2.forEach(function(e, index) {
checkedCopy.push(selectAll);
});
this.setState({
data: data2,
checked: checkedCopy,
selectAll: false
});
}
render() {
return (
<div>
<div className="container">
<ReactTable
data={this.state.data}
filterable
defaultFilterMethod={(filter, row) =>
row[filter.id] !== undefined
? String(row[filter.id])
.toLowerCase()
.includes(filter.value.toLowerCase())
: false
}
columns={[
{
Header: "One",
accessor: "one"
},
{
Header: <input type="checkbox" onChange={this.handleChange} />,
Cell: row => (
<input
type="checkbox"
defaultChecked={this.state.checked[row.index]}
/>
),
sortable: false,
filterable: false
},
{
Header: "Two",
accessor: "two"
},
{
Header: "Three",
accessor: "three"
}
]}
className="-striped "
/>
</div>
</div>
);
}
}
export default KKTable;

Figured it out. In case anyone needs the code:
import React, { Component } from "react";
import $ from "jquery";
import ReactTable from "react-table";
import "react-table/react-table.css";
const style = {
container: {
position: "relative"
},
refresh: {
cursor: "pointer",
width: "75px"
}
};
class KKTable extends Component {
constructor() {
super();
this.state = {
loading: true,
timestamp: "",
selectAll: false,
data: [],
checked: []
};
this.handleChange = this.handleChange.bind(this);
this.handleSingleCheckboxChange = this.handleSingleCheckboxChange.bind(
this
);
}
handleChange = () => {
var selectAll = !this.state.selectAll;
this.setState({ selectAll: selectAll });
var checkedCopy = [];
this.state.data.forEach(function(e, index) {
checkedCopy.push(selectAll);
});
this.setState({
checked: checkedCopy
});
};
handleSingleCheckboxChange = index => {
console.log(index);
var checkedCopy = this.state.checked;
checkedCopy[index] = !this.state.checked[index];
if (checkedCopy[index] === false) {
this.setState({ selectAll: false });
}
this.setState({
checked: checkedCopy
});
};
componentDidMount() {
const data2 = [
{ one: "hi0", two: "two0", three: "three0" },
{ one: "hi1", two: "two1", three: "three1" },
{ one: "hi2", two: "two2", three: "three2" },
{ one: "hi3", two: "two3", three: "three3" },
{ one: "hi4", two: "two4", three: "three4" },
{ one: "hi5", two: "two5", three: "three5" },
{ one: "hi6", two: "two6", three: "three6" },
{ one: "hi7", two: "two7", three: "three7" },
{ one: "hi8", two: "two8", three: "three8" }
];
var checkedCopy = [];
var selectAll = this.state.selectAll;
data2.forEach(function(e, index) {
checkedCopy.push(selectAll);
});
this.setState({
data: data2,
checked: checkedCopy,
selectAll: selectAll
});
}
render() {
console.log(this.state);
return (
<div>
<div className="container">
<ReactTable
data={this.state.data}
filterable
defaultFilterMethod={(filter, row) =>
row[filter.id] !== undefined
? String(row[filter.id])
.toLowerCase()
.includes(filter.value.toLowerCase())
: false
}
columns={[
{
Header: "One",
accessor: "one"
},
{
Header: (
<input
type="checkbox"
onChange={this.handleChange}
checked={this.state.selectAll}
/>
),
Cell: row => (
<input
type="checkbox"
defaultChecked={this.state.checked[row.index]}
checked={this.state.checked[row.index]}
onChange={() => this.handleSingleCheckboxChange(row.index)}
/>
),
sortable: false,
filterable: false
},
{
Header: "Two",
accessor: "two"
},
{
Header: "Three",
accessor: "three"
}
]}
className="-striped "
/>
</div>
</div>
);
}
}
export default KKTable;

Where are you pulling the filter.id from in row[filter.id] !== undefined?
This may cause some issues with how the child items are then selected

Related

REACTJ - convert class component to functionnal component

i'm new to react and i'm trying to convert this class based component to a functionnal component but i get an error of state, how can i convert it please ?
This is my components :)
sandbox link
Thank you
In this example, it is quite straight forward as there are no component life cycle methods. You can just define all the methods in the function, and return the component.
function Demo() {
const [state, setState] = React.useState({
expandedKeys: [],
autoExpandParent: true,
checkedKeys: [],
allCheckedKeys: [],
selectedKeys: [],
newTreeView: false,
newTreeData: []
});
const onExpand = (expandedKeys) => {
console.log("onExpand", expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setState({
...state,
expandedKeys,
autoExpandParent: false
});
};
const onCheck = (checkedKeys, e) => {
const allCheckedKeys = [...checkedKeys, ...e.halfCheckedKeys];
console.log("onCheck", allCheckedKeys);
console.log(createNewTreeData(treeData, allCheckedKeys));
setState((prevState) => ({
...prevState,
allCheckedKeys,
checkedKeys
}));
};
const onSelect = (selectedKeys, info) => {
console.log("onSelect", info);
setState({ ...state, selectedKeys });
};
const renderTreeNodes = (data) =>
data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item} />;
});
const createTree = () => {
setState((prevState) => ({
...prevState,
newTreeView: true,
newTreeData: createNewTreeData(treeData, prevState.allCheckedKeys)
}));
};
return (
<>
<Tree
checkable
onExpand={onExpand}
expandedKeys={state.expandedKeys}
autoExpandParent={state.autoExpandParent}
onCheck={onCheck}
checkedKeys={state.checkedKeys}
onSelect={onSelect}
selectedKeys={state.selectedKeys}
>
{renderTreeNodes(treeData)}
</Tree>
<button onClick={createTree}>Validate</button>
{state.newTreeView && <Tree>{renderTreeNodes(state.newTreeData)}</Tree>}
</>
);
}
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Tree } from 'antd';
const treeData = [
{
title: '0-0',
key: '0-0',
children: [
{
title: '0-0-0',
key: '0-0-0',
children: [
{
title: '0-0-0-0',
key: '0-0-0-0',
},
{
title: '0-0-0-1',
key: '0-0-0-1',
},
{
title: '0-0-0-2',
key: '0-0-0-2',
},
],
},
{
title: '0-0-1',
key: '0-0-1',
children: [
{
title: '0-0-1-0',
key: '0-0-1-0',
},
{
title: '0-0-1-1',
key: '0-0-1-1',
},
{
title: '0-0-1-2',
key: '0-0-1-2',
},
],
},
{
title: '0-0-2',
key: '0-0-2',
},
],
},
{
title: '0-1',
key: '0-1',
children: [
{
title: '0-1-0-0',
key: '0-1-0-0',
},
{
title: '0-1-0-1',
key: '0-1-0-1',
},
{
title: '0-1-0-2',
key: '0-1-0-2',
},
],
},
{
title: '0-2',
key: '0-2',
},
];
const Demo = () => {
const [expandedKeys, setExpandedKeys] = useState(['0-0-0', '0-0-1']);
const [checkedKeys, setCheckedKeys] = useState(['0-0-0']);
const [selectedKeys, setSelectedKeys] = useState([]);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const onExpand = (expandedKeysValue) => {
console.log('onExpand', expandedKeysValue); // if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
};
const onCheck = (checkedKeysValue) => {
console.log('onCheck', checkedKeysValue);
setCheckedKeys(checkedKeysValue);
};
const onSelect = (selectedKeysValue, info) => {
console.log('onSelect', info);
setSelectedKeys(selectedKeysValue);
};
return (
<Tree
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={treeData}
/>
);
};
ReactDOM.render(<Demo />, document.getElementById('container'));
I have updated the code using ES6 arrow functions resulting in shorter and simpler code than traditional functional components.
import React,{useState} from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Tree } from "antd";
const { TreeNode } = Tree;
const treeData = [
{
title: "0-0",
key: "0-0",
children: [
{
title: "0-0-0",
key: "0-0-0",
children: [
{ title: "0-0-0-0", key: "0-0-0-0" },
{ title: "0-0-0-1", key: "0-0-0-1" },
{ title: "0-0-0-2", key: "0-0-0-2" }
]
},
{
title: "0-0-1",
key: "0-0-1",
children: [
{ title: "0-0-1-0", key: "0-0-1-0" },
{ title: "0-0-1-1", key: "0-0-1-1" },
{ title: "0-0-1-2", key: "0-0-1-2" }
]
},
{
title: "0-0-2",
key: "0-0-2"
}
]
},
{
title: "0-1",
key: "0-1",
children: [
{ title: "0-1-0-0", key: "0-1-0-0" },
{ title: "0-1-0-1", key: "0-1-0-1" },
{ title: "0-1-0-2", key: "0-1-0-2" }
]
},
{
title: "0-2",
key: "0-2"
}
];
const createNewTreeData = (treeData, checkedKeys) => {
return treeData.reduce((acc, treeDataItem) => {
if (checkedKeys.includes(treeDataItem.key)) {
if (treeDataItem.children) {
acc.push({
...treeDataItem,
children: createNewTreeData(treeDataItem.children, checkedKeys)
});
} else {
acc.push(treeDataItem);
}
}
return acc;
}, []);
};
const Demo =()=> {
const [state,setState] = useState({
expandedKeys: [],
autoExpandParent: true,
checkedKeys: [],
allCheckedKeys: [],
selectedKeys: [],
newTreeView: false,
newTreeData: []
});
const onExpand = (expandedKeys) => {
console.log("onExpand", expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setState({
expandedKeys,
autoExpandParent: false
});
};
const onCheck = (checkedKeys, e) => {
const allCheckedKeys = [...checkedKeys, ...e.halfCheckedKeys];
console.log("onCheck", allCheckedKeys);
console.log(createNewTreeData(treeData, allCheckedKeys));
setState((prevState) => ({
...prevState,
allCheckedKeys,
checkedKeys
}));
};
const onSelect = (selectedKeys, info) => {
console.log("onSelect", info);
setState({ selectedKeys });
};
const renderTreeNodes = (data) =>
data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item} />;
});
const createTree = () => {
setState((prevState) => ({
...prevState,
newTreeView: true,
newTreeData: createNewTreeData(treeData, prevState.allCheckedKeys)
}));
};
return (
<>
<Tree
checkable
onExpand={onExpand}
expandedKeys={state.expandedKeys}
autoExpandParent={state.autoExpandParent}
onCheck={onCheck}
checkedKeys={state.checkedKeys}
onSelect={onSelect}
selectedKeys={state.selectedKeys}
>
{renderTreeNodes(treeData)}
</Tree>
<button onClick={createTree}>Validate</button>
{state.newTreeView && (
<Tree>{renderTreeNodes(state.newTreeData)}</Tree>
)}
</>
);
}
ReactDOM.render(<Demo />, document.getElementById("container"));

When a prop is changing const is backing to its initial values

I have this component which is a filter for a table..
handleSearch function is responsible to update const filters... its work perfectly when dataIndex props is the same, but when it changes, filters value is backing to it's initial value, an empty array.
I can't manage to resolve it, I've already console log everything.
import React, { useState, } from "react";
import { SearchOutlined } from "#ant-design/icons";
import { Select, Button, Space } from "antd";
const TableFilter = (props) => {
const {
filterType,
filterMode,
filterOptions,
FilterSelectOnFocus,
dataIndex,
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
} = props;
const [filters, setFilters] = useState([]);
const SelectFilter = (
<Select
style={{ width: 188, marginBottom: 8, display: "block" }}
type={filterType}
mode={filterMode}
name={dataIndex}
value={selectedKeys}
optionFilterProp="children"
placeholder={`Search ${dataIndex}`}
onFocus={FilterSelectOnFocus}
showSearch
onChange={(value) => setSelectedKeys(value ? value : [])}
getPopupContainer={(trigger) => trigger}
notFoundContent
>
{filterOptions?.map((type, key) => (
<Select.Option value={type.value} key={key}>
{type.label}
</Select.Option>
))}
</Select>
);
const defaultFilterTypes = [
{
type: "select",
element: SelectFilter,
},
];
const handleFilterType = () => {
const type = defaultFilterTypes.find((types) => types.type === filterType);
return type.element;
};
const handleSearch = () => {
console.log(filters) //is empty when dataIndex value change, when it's is the same it get the update value of the 75 line
confirm();
const newFilterValues = [...filters]
const index = newFilterValues.findIndex(newValue => newValue.searchedColumn === dataIndex)
if(index === -1){
newFilterValues.push({ searchText: selectedKeys, searchedColumn: dataIndex})
}
else{
newFilterValues[index] = {searchText: selectedKeys, searchedColumn: dataIndex}
}
setFilters(newFilterValues)
}
const handleReset = () => {
console.log('reset');
clearFilters();
setFilters({ searchText: "" });
setSelectedKeys([]);
};
return (
<div style={{ padding: 8 }}>
{handleFilterType()}
<Space>
<Button
type="primary"
onClick={() => handleSearch()}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button
onClick={() => handleReset()}
size="small"
style={{ width: 90 }}
>
Reset
</Button>
</Space>
</div>
);
};
export default TableFilter;
Table Component
import React, { useEffect, useState } from "react";
import { Table } from "antd";
import { getTransactions } from "../../../../api/Transactions";
import { formatCnpjCpf, formatCurrency } from "../../../../utils/masks";
import TableFilter from "../../../../shared-components/ant-design/containers/TableFilters";
import { getPartnersAsOptions } from "../../../../api/Partners";
const Insider = (props) => {
const [data, setData] = useState([]);
const [paginationValues, setPaginationValues] = useState({
current: 1,
pageSize: 50,
total: 0,
position: ["topRight"],
});
const [partners, setPartners] = useState([{value: null, label: 'carregando...'}])
const context = "insider";
function getColumnSearchProps(
dataIndex,
filterType,
filterMode,
filterOptions,
FilterSelectOnFocus
) {
return {
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => {
return (
<TableFilter
dataIndex={dataIndex}
filterType={filterType}
filterMode={filterMode}
filterOptions={filterOptions}
FilterSelectOnFocus={FilterSelectOnFocus}
setSelectedKeys={setSelectedKeys}
selectedKeys={selectedKeys}
confirm={confirm}
clearFilters={clearFilters}
/>
);
},
};
}
async function getPartners(){
if(partners.length > 2){
return
}
const response = await getPartnersAsOptions(paginationValues)
setPartners(response.data)
}
const columns = [
{
dataIndex: ["transactionType", "desc"],
title: "Tipo de Transação",
sorter: true,
key: "orderTransactionType",
...getColumnSearchProps("orderTransactionType"),
},
{
dataIndex: "transactionDate",
title: "Data Transação",
key: "orderTransactionDate",
sorter: true,
...getColumnSearchProps("orderTransactionDate"),
},
{
title: "Nome origem",
dataIndex: ["source", "name"],
sorter: true,
key: "orderSourceCustomerName",
},
{
render: (render) => formatCnpjCpf(render.source.document.value),
title: "Documento origem",
key: "sourceCustomer",
...getColumnSearchProps("sourceCustomer", "select", "tags")
},
{
title: "Nome destino",
dataIndex: ["target", "name"],
sorter: true,
key: "orderTargetCustomerName",
},
{
render: (render) => formatCnpjCpf(render.target.document.value),
title: "Documento destino",
},
{
render: (render) => formatCurrency(render.value),
title: "Valor da transação",
key: "orderValue",
sorter: true,
align: "right",
},
{
render: (render) => formatCurrency(render.chargedTariff),
title: "Tarifa",
key: "orderChargedTariff",
sorter: true,
align: "right",
},
{
render: (render) => formatCurrency(render.cost),
title: "Custo",
key: "orderCost",
sorter: true,
align: "right",
},
{
render: (render) => formatCurrency(render.revenue),
title: "Receita",
key: "orderRevenue",
sorter: true,
align: "right",
},
{
title: "Parceiro",
name: "Parceiro",
dataIndex: ["partner", "name"],
key: "orderPartnerName",
sorter: true,
align: "center",
...getColumnSearchProps(
"orderPartnerName",
"select",
"multiple",
partners,
getPartners)
},
{
title: "id da transação",
name: "id da transação",
dataIndex: "id",
},
];
useEffect(function transactions() {
async function fetchTransactions() {
const response = await getTransactions(context, paginationValues);
if (response) {
const { data, pagination } = response;
setData(data);
setPaginationValues(pagination);
}
}
fetchTransactions();
// eslint-disable-next-line
}, []);
return <Table dataSource={data} columns={columns} />;
};
export default Insider;
You could move this piece of code
const [filters, setFilters] = useState([]);
In a higher level

Pass dynamic content to the react table sub component

I am using react table v6 for grid purposes. I am trying to implement a subcomponent where in the data to this sub component needs to be passed dynamically. This sub component should expand and collapse on click of arrows. I have tried the following , but the sub component is not rendering any data. I am creating a wrapper for this, the data to the subcomponent should be passed dynamically based on the source data.
https://codesandbox.io/s/react-table-row-table-subcompoentn-sk14i?file=/src/DataGrid.js
import * as React from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";
export default class DataGrid extends React.Component {
renderSubComponent = original => {
console.log(original);
return (
original.nested &&
original.nested.map((i, key) => (
<React.Fragment key={key}>
<div>{i.name}</div>
<div>{i.value}</div>
</React.Fragment>
))
);
};
render() {
return (
<ReactTable
data={this.props.data}
columns={this.props.columns}
SubComponent={this.renderSubComponent}
/>
);
}
}
import * as React from "react";
import { render } from "react-dom";
import DataGrid from "./DataGrid";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
columns: [],
allData: []
};
}
componentDidMount() {
this.getData();
this.getColumns();
}
getData = () => {
const data = [
{
firstName: "Jack",
status: "Submitted",
nested: [
{
name: "test1",
value: "NA"
},
{
name: "test2",
value: "NA"
}
],
age: "14"
},
{
firstName: "Simon",
status: "Pending",
nested: [
{
name: "test3",
value: "NA"
},
{
name: "test4",
value: "Go"
}
],
age: "15"
}
];
this.setState({ data });
};
getColumns = () => {
const columns = [
{
Header: "First Name",
accessor: "firstName"
},
{
Header: "Status",
accessor: "status"
},
{
Header: "Age",
accessor: "age"
}
];
this.setState({ columns });
};
onClickRow = rowInfo => {
this.setState({ allData: rowInfo }, () => {
console.log(this.state.allData);
});
};
render() {
return (
<>
<DataGrid
data={this.state.data}
columns={this.state.columns}
rowClicked={this.onClickRow}
/>
</>
);
}
}
render(<App />, document.getElementById("root"));
try spread the argument and it will work :
...
renderSubComponent = ({original}) => {
...

React-select how to filter out already chosen values?

I have a select component defined like this:
this.state.list = [{label: "test1", value:1}, {label:"test2", value:2}, {label:"test3", value:3}]
this.state.selected = [{label:"test2", value:2}]
let listMap = this.state.list
let list = this.state.list
{listMap.length !== 0 ? listMap.map((item: any, key: number) => (
<div>
<Select
id="list for data"
options={list}
onChange={value => selectList(value)}
placeholder="Select Your Option"
/>
<div/>
))
I want is after test2 is selected, I want the other two drop downs to show test1, and test3.
What I have done so far:
let y = this.state.selected.map(itemY => { return itemY.value })
let x = list.filter(itemX => !yFilter.includes(itemX.value)) // [{value: 1, label:"test1"},{value: 3, label: "test3"}]
And then replacing options property as x.
The filters are working but,
The place holder is not updating the selected values.
What I want to achieve:
And for the next drop down [1], be only able to select those which aren't selected:
You have to separate the three react selects. As you are applying filter on one it will be applicable to all react select.The filtering will also remove in all react select. You can checkout following example.
https://codesandbox.io/s/react-select-5u3rh
import React from "react";
import {
render
} from "react-dom";
import ReactDOM from "react-dom";
import Select from "react-select";
import "react-select/dist/react-select.css";
class ReactSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
itemtitle: "",
multi: true,
multiValue: "eeee...",
options: [{
value: "Color",
label: "Yellow"
},
{
value: "Fruit",
label: "Apple"
},
{
value: "Tool",
label: "Spanner"
}
],
options2: [{
value: "Color",
label: "Yellow"
},
{
value: "Fruit",
label: "Apple"
},
{
value: "Tool",
label: "Spanner"
}
]
};
}
onTitleChange(e, value) {
this.setState({
[e.target.name]: e.target.value
});
this.setState({
multiValue: e.target.value
});
}
handleOnChange(obj) {
this.setState({
multiValue: obj
});
this.setState({
options2: this.state.options2.filter(v => v.value !== obj.value)
})
}
handleOnChange2(obj) {
this.setState({
multiValue2: obj
});
}
render() {
return ( <
div >
<
Select
// multi={this.state.multi}
options = {
this.state.options
}
onChange = {
this.handleOnChange.bind(this)
}
value = {
this.state.multiValue
}
isSearchable = {
false
}
placeholder = "eee" /
>
<
Select
// multi={this.state.multi}
options = {
this.state.options2
}
onChange = {
this.handleOnChange2.bind(this)
}
value = {
this.state.multiValue2
}
isSearchable = {
false
}
placeholder = "eee" /
>
<
/div>
);
}
}
ReactDOM.render( < ReactSelect / > , document.body);
your state should look like this
state = { items : [{value: 1, label:"test1", selected:false},{value: 1, label:"test2", selected:false},{value: 3, label: "test3", selected:false}]
Then when an option is clicked, it sets the key "selected" to true. Afterward, only map the objects with selected false as dropdown items. Remember to use setState.

Showing error whenever optional props are being sent to a child component

I am trying to optional have row-select features and this should be determined based on a prop that is being passed from parent. I have two grids on a single page, where in one has prop that should enable row selection and the other one does not. But I am getting this error "Cannot read property 'className' of undefined " .
Sandbox: https://codesandbox.io/s/react-table-row-table-alternate-single-row-working-5fr81
import * as React from "react";
import { render } from "react-dom";
import DataGrid from "./DataGrid";
import ShowMore from "./ShowMore";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
columns: []
};
}
componentDidMount() {
this.getData();
this.getColumns();
}
getData = () => {
const data = [
{ firstName: "Jack", status: "Submitted", items: [1, 2, 3, 4] },
{ firstName: "Simon", status: "Pending", items: [1, 2] },
{ firstName: "Syls", status: "Pending", items: [1] },
{ firstName: "Pete", status: "Approved", items: [] }
];
this.setState({ data });
};
getColumns = () => {
const columns = [
{
Header: "First Name",
accessor: "firstName"
},
{
Header: "Status",
accessor: "status"
},
{
Header: "Items",
accessor: "items",
Cell: row => <ShowMore value={row.value} />
}
];
this.setState({ columns });
};
onClickRow = rowInfo => {
this.setState({ allData: rowInfo }, () => {
console.log(this.state.allData);
});
};
render() {
return (
<>
<DataGrid
data={this.state.data}
columns={this.state.columns}
rowClicked={this.onClickRow}
/>
<DataGrid data={this.state.data} columns={this.state.columns} />
</>
);
}
}
In your onRowClick function in DataGrid.js, your function will return nothing on first render (or until something is clicked). ReactTable is expecting SOMETHING here. If you supply an empty object, it will successfully render.

Categories