Currently, I am using functional react components with react hook useState
and an AgGridReact
Component.
I am displaying an AgGridReact
and put a onCellClicked
function on a AgGridColumn
. So far everything is working. In the onCellClicked
function I want to update my state and do something depending on its current value.
Here is the problem:
if I want to use my state get/set (useState
hook) inside of the onCellClicked
function it is not working as expected. For some reason, I can not update my state.
In a react class component it is working.
EDIT: I experimented for a while and found out that in the onCellClicked
function I have only the default value in myText. I can update it once. If I spam the onCellClicked
function it will append the text again to the default value from useState("default myText");
. I would expect that the string would get longer as often I click on the cell. Just as in my Class Component example.
If I use a simple button outside of the AgGridReact
<button onClick={() => setMyText(myText + ", test ")}>add something to myText state</button>
it is working as expected, the string gets longer every time I click on my <button>
. If I change the state of myText via the <button>
outside of the AgGridReact
and then click on the cell function again the state previously setted through my <button>
is lost.
Example react hook component:
import React, { useState } from 'react';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
function App() {
const [myText, setMyText] = useState("default myText");
const [todoListRowData, setTodoListRowData] = useState([]);
// ....fetch data and set the todoListRowData state....
const myCellClickFunction = (params, x) => {
// here is the problem:
// no matter how often I click in the cell myText is every time the default value 'default myText'
// EDIT: I found out I can update the state here but only from the initial default value once, myText is on every cell click again "default myText" and will be concatenated with "hookCellClicked". So every time I click this cell the state gets again "default myTexthookCellClicked"
console.log(myText);
setMyText(myText + "hookCellClicked");
}
return (
<div className="ag-theme-alpine" style={{ height: '600px', width: '100%' }}>
<AgGridReact rowData={todoListRowData} >
<AgGridColumn headerName="ID" field="id" maxWidth="50"></AgGridColumn>
<AgGridColumn headerName="UserId" field="userId" maxWidth="85"></AgGridColumn>
<AgGridColumn headerName="Title" field="title" minWidth="555"></AgGridColumn>
<AgGridColumn headerName="completed" field="completed"></AgGridColumn>
<AgGridColumn headerName="Testcol" onCellClicked={(params) => myCellClickFunction(params)}></AgGridColumn>
</AgGridReact>
</div>
}
export default App;
If I do the exact same thing in a class component it is working fine.
Example Class Component:
import React from 'react';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
class MyClassComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
myClassComponentRowData: [],
testState: "defaul testState"
};
}
// ....fetch data and set ag grid rowData state....
handleCellClick = (params) => {
// here everything works just fine and as expected
// every time I click on the cell the state testState updates and it is added ", handleCellClick" every time
console.log(this.state.testState);
this.setState({testState: this.state.testState + ", handleCellClick"});
}
render() {
return <div className="ag-theme-alpine" style={{ height: '600px', width: '100%' }}>
<AgGridReact rowData={this.state.myClassComponentRowData} >
<AgGridColumn headerName="ID" field="id" maxWidth="50"></AgGridColumn>
<AgGridColumn headerName="UserId" field="userId" maxWidth="85"></AgGridColumn>
<AgGridColumn headerName="Title" field="title" minWidth="555"></AgGridColumn>
<AgGridColumn headerName="completed" field="completed"></AgGridColumn>
<AgGridColumn headerName="Testcol" onCellClicked={(params) => this.handleCellClick(params)}></AgGridColumn>
</AgGridReact>
</div>
}
}
export default MyClassComponent;
Am I doing something wrong? I want to use a functional component with react hooks.