Cannot change hidden column state from true to false on setState - reactjs

I'm using devexpress React table and you can hide and show columns via state.
I would like to change the state for hidden from true to false but I get an Uncaught Invariant Violation error.
I've tried to use setState but doesn't work.
class ResultsTable extends Component {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'agent', title: 'Agent' },
{ name: 'alertGroup', title: 'Alert Group', hidden:true },
{ name: 'manager', title: 'Manager', hidden:true }
],
};
}
componentDidMount() {
this.testAlert();
}
testAlert = () => {
if (this.props.alertgroupColumn()) {
this.setState({
columns: [{ name: 'alertGroup', title: 'Alert Group', hidden:false }]
})
}
}
Hidden should change from true to false.

I have another alternative to update your state
class ResultsTable extends Component {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'agent', title: 'Agent' },
{ name: 'alertGroup', title: 'Alert Group', hidden:true },
{ name: 'manager', title: 'Manager', hidden:true }
],
};
}
componentDidMount() {
this.testAlert();
}
testAlert = () => {
if (this.props.alertgroupColumn()) {
//---- get the columns from state
let columns = JSON.parse(JSON.stringify(this.state.columns))
columns[1].hidden = false
this.setState({
columns:columns
})
this.setState({
columns: [{ name: 'alertGroup', title: 'Alert Group', hidden:false }]
})
}
}

Related

Objects are not valid as a React child error in React Datatable

OK, so Im getting this error when trying to return some data from my web api. Ive tried all as suggested on other similar posts but cant get this working. Any help appreciated.
Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
clg(records) returns this:
[{
id:1,
Listing: {id: 2, title: 'Testtt'},
ListingId: 2
},
{
id:2,
Listing: {id: 3, title: 'hell world'},
ListingId: 3
}]
here is my reactjs code:
class Products extends Component {
constructor(props) {
super(props);
this.columns = [
{
key: "id",
text: "Id",
className: "id",
align: "left",
sortable: true,
},
{
id:"ListingId"
text: "Merchant ID",
className: "name",
align: "left",
sortable: true,
},
}
];
this.state = {
records: []
};
this.getData = this.getData.bind(this);
}
componentDidMount() {
this.getData()
};
componentWillReceiveProps(nextProps) {
this.getData()
}
getData() {
axios
.get("/api/products")
.then(res => {
this.setState({ records: res.data})
})
.catch()
}
render() {
const {records}=this.state;
console.log(records);
return (
<div>
<ReactDatatable
records={this.state.records}
columns={this.columns}
loading='true'
/>
</div>
);
}}
Currently its displaying ListingId in the column, how can i display the Listing title instead?
i am currently using this package :
https://www.npmjs.com/package/#ashvin27/react-datatable
Here is the solution to my question
{
key:'ListingId',
text: "Column Title",
className: "name",
align: "left",
sortable: true,
cell: record => {
console.log(record)
return (
<span>{record.Listing.title}</span>)
}
},

React Hooks in TypeScript to Classes

I'm not use React Hook in TypeScript but I have a few lines of code like below:
const [columns] = React.useState<Column[]>([
{ name: 'product', title: 'Product' },
{ name: 'region', title: 'Region' },
{ name: 'amount', title: 'Sale Amount' },
{ name: 'saleDate', title: 'Sale Date' },
{ name: 'customer', title: 'Customer' },
]);
const [rows] = React.useState<ISale[]>(sales);
const [pageSizes] = React.useState<number[]>([5, 10, 15]);
const [currencyColumns] = React.useState<string[]>(['amount']);
I want to use these React Hook in Class but I don't know how to convert them!
Can someone help me? Thanks!
This is how you use class based components when you are working with TypeScript and React.
First, you need to define an interface or type alias for your class component's state/props.
interface YourComponentState {
columns: Column[];
rows: ISale[];
pageSizes: number[];
currencyColumns: string[];
}
Then, you will need to supply the generic type parameters for React.Component with the types for the props/state.
class YourComponentName extends React.Component<{}, YourComponentState> {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'product', title: 'Product' },
{ name: 'region', title: 'Region' },
{ name: 'amount', title: 'Sale Amount' },
{ name: 'saleDate', title: 'Sale Date' },
{ name: 'customer', title: 'Customer' },
],
rows: sales,
pageSizes: [5, 10, 15],
currencyColumns: ['amount'],
}
}
}
In class based react components, you cannot use hooks.
so, if you want something to store in state of class based component. you are going to:
class YourComponentName extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'product', title: 'Product' },
{ name: 'region', title: 'Region' },
{ name: 'amount', title: 'Sale Amount' },
{ name: 'saleDate', title: 'Sale Date' },
{ name: 'customer', title: 'Customer' },
],
rows: sales,
pageSizes: [5, 10, 15],
currencyColumns: ['amount']
}
}
}
you can access them in your component:
this.state.columns

How can I display the current value from a chart?

I am new to React and I work on a small project basically, I have a chart and I just want to display the current value from the chart.
For example, I have a chart with 4 random values:[5,2,5,1], so I want to have displayed the current value below the chart like first is 5, second is 2 and so on.
Here is my part of code:
class App extends React.Component {
addPoint = (point) => {
currentData = this.state.options.series[0].data
this.setState({
options: {
series: [
{ data: [...currentData, point]}
]
}
});
}
constructor(props) {
super(props);
this.internalChart = undefined;
this.dataStream = new DataStream();
this.dataStream.setUpdateCallback(this.addPoint);
this.state = {
options: {
chart: {
events: {
load: function () {
}
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 2
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: [[(new Date()).getTime(), 0]]
}]
}
};
}
render() {
return (
<HighchartsReact
constructorType={"stockChart"}
highcharts={Highcharts}
options={this.state.options}
/>
);
}}
Based on your snippet code, try to make random method by using function
Math.floor(Math.random() * Math.floor(max))
And then assign the options to HighchartsReact,
Full code on sandbox: https://codesandbox.io/s/headless-dream-0lzj1

Use destructuring assignment inside state

class BottomPanelProgramTabs extends React.Component<Props, State> {
state = {
activeTab: this.props.children[0].props.label,
};
...
ESLint want me to use destructuring assignment on
this.props.children[0].props.label
any ideas on how to do that?
you can do like this.
For more reference about prefer-destructuring
class BottomPanelProgramTabs extends React.Component<Props, State> {
constructor(){
let [props] = this.props.children;
state = {
activeTab : props.label
}
}
class BottomPanelProgramTabs extends React.Component<Props, State> {
state = {
activeTab: 'default label'
};
componentDidMount = () => {
const [{ props: { label } }] = this.props.children;
this.setState({
activeTab: label || 'default label',
...
})
}
...
You can mix destructing by getting the first element with [] and get the props with {}.
For example:
using [child] will give us the first element in the array.
const children = [{
props: {
label: 'Some label'
}
},
{
props: {
label: 'Second label'
}
},
,
{
props: {
label: 'another label'
}
}]
const [child] = children;
console.log(child);
to get props we can continue mixing our destruction by adding [ {props} ] which returns props object.
const children = [{
props: {
label: 'Some label'
}
},
{
props: {
label: 'Second label'
}
},
,
{
props: {
label: 'another label'
}
}]
const [ {props} ] = children;
console.log(props);
to get the label from props will can do this [{ props: { label } }]
const children = [{
props: {
label: 'Some label'
}
},
{
props: {
label: 'Second label'
}
},
,
{
props: {
label: 'another label'
}
}]
const [{ props: { label } }] = children;
console.log(label);
With complex data
const children = [{
props: {
label: [{
data: {
title: 'complex destructor'
}
},
{
data: {
title: 'complex destructor 2'
}
}]
}
},
{
props: {
label: 'Second label'
}
},
,
{
props: {
label: 'another label'
}
}]
const [{ props: { label: [ { data: { title } } ] } }] = children;
console.log(title)

Using state in method - React

I've got a method called devCreateSteps and I want to use state in that but it throws an error saying;
Uncaught TypeError: Cannot read property 'isTemplateUsed' of undefined
Here's the snippet of my code;
constructor() {
super();
this.state = {
modalVisible: false,
tableLoading: false,
modalHeader: "",
isTemplateUsed: false
};
}
devCreateSteps = [{
title: 'Info',
content: (<StepOne isTemplateUsed={this.state.isTemplateUsed} />),
}, {
title: 'Device',
content: (<StepTwo />),
}, {
title: 'Location',
content: (<StepThree />),
},
{
title: 'Properties',
content: (<StepFour />),
},
{
title: 'Controls',
content: (<StepFive />),
},
{
title: 'Summary',
content: (<StepFinal />),
}];
The problem is I can't use
isTemplateUsed={this.state.isTemplateUsed}
this in the devCreateSteps
What is the right way to use state to send it as props ?
Instead of defining devCreateSteps as a class property directly in class, do it in the componentWillMount function.
class App extends React.Component {
constructor() {
super();
this.state = {
modalVisible: false,
tableLoading: false,
modalHeader: "",
isTemplateUsed: false
};
}
componentWillMount() {
this.devCreateSteps = [{
title: 'Info',
content: (<StepOne isTemplateUsed={this.state.isTemplateUsed} />),
}, {
title: 'Device',
content: (<StepTwo />),
}, {
title: 'Location',
content: (<StepThree />),
},
{
title: 'Properties',
content: (<StepFour />),
},
{
title: 'Controls',
content: (<StepFive />),
},
{
title: 'Summary',
content: (<StepFinal />),
}];
}
}
Also define state as a property intializer too.
class App extends React.Component {
state = {
modalVisible: false,
tableLoading: false,
modalHeader: "",
isTemplateUsed: false
};
devCreateSteps = [{
title: 'Info',
content: (<StepOne isTemplateUsed={this.state.isTemplateUsed} />),
}, {
title: 'Device',
content: (<StepTwo />),
}, {
title: 'Location',
content: (<StepThree />),
},
{
title: 'Properties',
content: (<StepFour />),
},
{
title: 'Controls',
content: (<StepFive />),
},
{
title: 'Summary',
content: (<StepFinal />),
}];
}
P.S. make sure you have stage-2 added as a preset to babel in you
webpack config, since property initializers are not part of ES6.
Uncaught TypeError: Cannot read property 'isTemplateUsed' of undefined
Because you are using state variable named open before initializing , you can avoid this error by two ways either
try to initialize variable with empty array and then assign values using state wihtin constructor.
devCreateSteps: [];
constructor(props, state) {
super(props, state);
this.state = {
open: this.props.open
}
console.log(this.props, this.state);
this.devCreateSteps = [{
title: 'Info',
content: (<p isTemplateUsed={this.state.open} />)
}]
}
or you can use componentWillMount as suggested in above answer.

Resources