Hi there,
I’ve been trying to implement this gantt component in my application for a while.
I am new to react, so I may not be implementing the best way, but I am trying to.
I am having a problem to reload my tasks after closing the component and opening it again.
I was able to make it work the way I want, but let me give you an idea of my scenario here:
In my application the user is able to create many projects, and each project should display its many actions on Gantt. That’s my goal with the component. So, basically, the user sees his projects in a list and he is able to load the tasks of any project in this list.
Whenever I close the component in order to load tasks of other project, I am getting an error related to the state variable. Therefore, I am not sure if I am using it the correct way.
I have been following the tutorial provided in the website, pretty easy to set up by the way.
I my list I call for “edit-gantt.jsx”, which will render the gantt component:
[code] render (){
let acoes = this.state.acoes && this.state.acoes.map((acao) => (
{
//setting state in componentDidMount. I go to my controller, and return a list of tasks
// state will map my tasks in a list here
}
));
let data = {
data:[].concat(acoes)
};
return(
<Content titulo="Gantt">
<Row>
<Col md={12}>
<LoadingContainer isLoading={this.state.isLoading}>
<div style={{marginTop: 15, height: 700, padding:5}}>
<div className="gantt-container">
{
acoes &&
<Gantt
tasks={data}
zoom={this.state.currentZoom}
onTaskUpdated={this.handleTaskUpdate}
onLinkUpdated={this.logLinkUpdate}
configuracoesColunas={this.state.configuracoes}
newTasks={data}
handleCloseAcao={this.handleCloseAcao}
itemId={this.props.params.id}
/>
}
</div>
</div>
</LoadingContainer>
</Col>
</Row>
</Content>
);
}[/code]
Now, here is my gantt component that will be rendered:
[code]
export default class Gantt extends React.Component {
constructor(props){
super(props);
}
shouldComponentUpdate(nextProps){
// if (this.props.tasks.data.length !== nextProps.tasks.data.length){
// return true
// }
// if (this.props.zoom !== nextProps.zoom){
// return true
// }
//else {return false}
gantt.clearAll();
gantt.parse(nextProps.tasks); // loading new tasks
gantt.refreshData();
return this.props.zoom !== nextProps.zoom;
}
componentDidUpdate() {
gantt.render();
}
//componentWillMount(){
// gantt.init(this.ganttContainer);
//}
componentWillUnmount(){
gantt.clearAll();
//gantt.destructor();
//gantt.detachEvent()
}
handleClose(){
this.props.handleCloseAcao();
}
componentDidMount() {
// configurando as colunas do gantt
gantt.config.columns = [
my columns
];
if(!gantt.$eventsAttached){
gantt.$eventsAttached = true;
gantt.attachEvent('onTaskDblClick', (id) => {
if (id != null){
let task = gantt.getTask(id);
ContentManager.addContent(<AcaoEdit
item={task}
id={id}
handleClose={this.handleClose}
itemId={this.props.itemId}>
</AcaoEdit>);
}
return false;
});
/*
gantt.attachEvent("onDestroy", () => {
console.log("destrói gantt");
});*/
}
gantt.config.layout = {
css: "gantt_container",
rows:[
{
cols: [
{view: "grid", id: "grid", scrollX:"scrollHor", scrollY:"scrollVer"},
{resizer: true, width: 1},
{view: "timeline", id: "timeline", scrollX:"scrollHor", scrollY:"scrollVer"},
{view: "scrollbar", scroll: "y", id:"scrollVer"}
]
},
{view: "scrollbar", scroll: "x", id:"scrollHor", height:20}
]
};
gantt.init(this.ganttContainer);
gantt.parse(this.props.tasks);
}
render() {
this.setZoom(this.props.zoom);
return (
<div
ref={(input) => this.ganttContainer = input }
style={{width: ‘100%’, height: ‘400’}}
>
);
}
}[/code]
This is not the entire code, I removed a few things in order to make it easier to understand my scenario.
Here is my problem, with this code I was able to make it work.
I send my tasks to the component, it gets rendered, and then “componentDidMount” loads my tasks. To create new tasks I’ve created my own method. There is a button that opens a modal, the user inserts data, saves, and then I call a method “handleClose” that will update my state variable loading tasks from the back end again. This is working fine, until I close gantt, return to my list of projects and try to load tasks of another project.
I left some commented lines in the code so you know a few different things I’ve tried already.
There seems to be an issue with state, here is the error I am getting:
warning.js:33 Warning: setState(…): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the FormEdit component.
Last thing I tried was to use the destructor:
componentWillUnmount(){
gantt.clearAll();
gantt.destructor();
//gantt.detachEvent()
}
When I close the component, and try to open again, it returns me:
dhtmlxgantt.js:10 Uncaught (in promise) TypeError: Cannot read property ‘tasksStore’ of undefined
Taking a look at the DOM, was removed, but the is still there empty.
Am I doing it wrong? Does anybody have a better idea of how to use the component?