Vikram Saini
Vikram Saini

Reputation: 2771

Retain state data on re render in reactjs

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

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

enter image description here

Here is the screenshot after adding second main task enter image description here

Upvotes: 0

Views: 769

Answers (1)

Loonger
Loonger

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

Related Questions