Reputation: 2771
I cannot share the whole code as it is very complex.
The app is basically a todo list task in which we can add main task and subtasks corresponding to main tasks
Structure is like this
Main task 1
1.
2.
3.
Now i maintain an index variable in my json structure and when send my data to the child component as
this.state.Todo[index].items
Now the problem i am facing is
But if i add second task this.state.Todo1.items then child componen only gets data for second index and subtasks of first child that i previously added disappears from the page.
Main task 1
//Disappears
Main task 2
1.
2.
3.
I am not able to figure it out how to solve this issue
UPDATE:
here is my json
{
Todo:[
{name:"primary",
items:[
{
item:'',
isDone:false,
cost:0}
]
}
],
filter:[
{
keyword:'',
Status:"SHOW_ALL"
}
],
selectedCatelog:"0"};
**starting Component todoAdd.js**
var React=require('react');
var ReactDOM=require('react-dom');
import TodoBanner from './TodoComponents/TodoBanner.js';
import TodoForm from './TodoComponents/TodoForm.js';
import TodoList from './TodoComponents/TodoList.js';
import TodoCost from './TodoComponents/TodoCost.js';
var TodoApp = React.createClass({
getInitialState : function(){
return {Todo:[{name:"primary",items:[{item:'',isDone:false,cost:0}
]}],filter:[{keyword:'',Status:"SHOW_ALL"}],selectedCatelog:"0"};
},
updateItems: function(newItem){
var item = {item:newItem.item,isDone:false,cost:newItem.cost};
var newtodo = this.state.Todo;
var allItems = this.state.Todo[this.state.selectedCatelog].items.concat([item]);
newtodo[this.state.selectedCatelog].items = allItems;
this.setState({
Todo: newtodo
});
},
deleteItem : function(index){
var newtodo = this.state.Todo;
var allItems = this.state.Todo[this.state.selectedCatelog].items.slice(); //copy array
allItems.splice(index, 1); //remove element
newtodo[this.state.selectedCatelog].items = allItems;
this.setState({
Todo: newtodo
});
},
filterItem : function(e){
this.state.filter[0].Status = e.target.value;
this.setState({
filter: this.state.filter
});
},
searchItem : function(e){
this.state.filter[0].keyword = e.target.value;
this.setState({
filter: this.state.filter
});
},
AddCatalog: function(newCatalog){
var Catalog = {name:newCatalog,items:[]};
var newtodo = this.state.Todo.concat([Catalog]);
this.setState({
Todo: newtodo
});
},
setID:function(index)
{
if(index-this.state.selectedCatelog===1)
{
this.setState({
selectedCatelog: index
});
}
},
setSelectedCatalog: function(index){
},
setIndexItem:function(index)
{
this.setState({
selectedCatelog: index
});
},
render: function(){
console.log(JSON.stringify(this.state.Todo))
const AppBarExampleIcon = () => (
<AppBar title="Module Cost Estimation" />
);
return (
<div>
<div>
<MuiThemeProvider>
<AppBarExampleIcon />
</MuiThemeProvider>
<TodoCost cost={this.state.Todo}/>
<ToDoCatalogForm onFormSubmit = {this.AddCatalog} />
<ToDoCatelog setItemId={this.setIndexItem} set={this.updateItems} onSelectDemo={this.setID} selectedID = {this.state.selectedCatelog} onSelected={this.setSelectedCatalog} Todos = {this.state.Todo} />
</div>
<div>
<TodoList ListIndex={this.state.selectedCatelog} items = {this.state.Todo} filter = {this.state.filter} onDelete={this.deleteItem}/>
<ToDoFilter onFilter = {this.filterItem} onSearch = {this.searchItem} filter={this.state.filter}/>
</div>
</div>
);
}
});
ReactDOM.render(<TodoApp />, document.getElementById("app"));
When i Add a task its name gets added in name property of Json and when i enter subtasks then subtasks are populated in items property corressponding to the name and i am updating the index using selectedCatelog.Whenever a new task is added selectedCatelog is updated in setIndexItem method and then i pass entire json to TodoList Component
Here is the screenshot before adding second main task
Here is the screenshot after adding second main task
Upvotes: 0
Views: 769
Reputation: 110
For the few information you give us it looks like the problem is updating the state.
When you update a member of the state you overwrite that member with the new one, so you have to take the information you had before and add the new one.
Besides, you can't directly mutate the state like this.state.Todo.push(newTodo)
, so being Todo an array you should use a method like concat to add a new element as it returns a new Array.
const { Todo } = this.state;
let newTodo = {"name":'sec',"items":[2,4,5,7]}
this.setState({ Todo:Todo.concat([newTodo])});
Upvotes: 1