3

I have data in parent's component state like this:

data=[
            {key:0,name="abc",value="123"},
            {key:1,name="def",value="456"},
            {key:2,name="ghi",value="789"}
     ]

In my react component I am calling child components as list in the return part of the parent component as shown below.

class MyApp extends React.Component{
  constructor(props) {
    super(props);
     this.state = {
      record={
        name="",
        timestamp="",
        data =[
          {key:0,name="abc",value="123"},
          {key:1,name="def",value="456"},
          {key:2,name="ghi",value="789"}
        ]
    }
    this.deleteFromStateArray=this.deleteFromStateArray.bind(this);
  }

  deleteFromStateArray(key){
    let oldData = [...this.state.record.data];
    let newData= [];
    oldData.map(function (record, i) {
      if (record.key != key) {
        newData.push(record);
      }
    })
    newData.map(function (record, i) {
      newData[i].key = i + 1
    })
    this.setState({ record: Object.assign({}, this.state.record, { data: newData }), });
  }
  render() {

  return(
    {
      this.state.data.map((record,index) => 
             <Child key={record.key}
              id={record.key}
              name={record.name}
              value={record.value}
              onDelete={this.deleteFromStateArray} />
    }
  )
  }

I am calling onDelete() in the child component like this <button onClick={this.props.onDelete(this.state.id)} /> \\ I am initializing id as key in state inside constructor in child

My problem is when I am calling onDelete in the child class I am able to remove the obj with key=1 properly in the function but rerendering is not happening properly.

What I mean is state is getting set properly with only 2 items in data 1 with key=0 and other with key=2. But what i see in GUI is 2 child components 1 with key 0 and second one with key=1 which is cxurrently not present in the state data.

Can anybody help me with re-rendering the data properly?

I also want to change the key ordering after deleting from array in setState

3 Answers 3

1

React uses key to work out if elements in the collection need to be re-rendered. Keys should be unique and constant. In your method you are changing key property of your records and this probably leads to described error.

Also, you can replace all your code with simple filter call like this:

this.setState(oldState => ({ 
    record: {
        ...oldState.record, 
        { 
            data: oldState.record.data.filter(item => item.key !== key)
        }
    }
});

It is also worth mentioning that you should keep your state as flat as possible to simplify required logic. In your case removing record and and leaving it as below would be a good idea:

this.state = {
    name: "",
    timestamp: "",
    data: [
      {key:0,name: "abc",value: "123"},
      {key:1,name: "def",value: "456"},
      {key:2,name: "ghi",value: "789"}
    ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

what is this syntax. can i get detailed info on what it is doing as i am new to react
ok, so instead of creating new array by` map` & push as you did I just used filter; then I modified your setState a bit to ensure it works on current state - more info here: reactjs.org/docs/react-component.html#setstate
will this syntax set state work only in JS file (mine is JSX) because i am getting error in visual studio code like [js] Property assignment expected.
0

I'm not certain if this actually worked for you but the function declaration for deleteFromStateArray is inside the render function.

I think your component should look like this:

class MyApp extends React.Component{
  constructor(props) {
    super(props);

    this.state = {
      record={
        name="",
        timestamp="",
        data =[
          {key:0,name="abc",value="123"},
          {key:1,name="def",value="456"},
          {key:2,name="ghi",value="789"}
        ]
    }
    this.deleteFromStateArray=this.deleteFromStateArray.bind(this);
  }

  deleteFromStateArray(key){
    let oldData = [...this.state.record.data];
    let newData= [];
    oldData.map(function (record, i) {
      if (record.key != key) {
        newData.push(record);
      }
    })
    newData.map(function (record, i) {
      newData[i].key = i + 1
    })
    this.setState({ record: Object.assign({}, this.state.record, { data: newData }), });
  }
  render() {
    return(
      {
        this.state.record.data.map((record,index) => 
          <Child key={record.key}
            id={record.key}
            onDelete={this.deleteFromStateArray} />
      }
    )
  }
}

4 Comments

my bad the implemented way is like that only. I will correct my that in my question. But the problem remains the same
There must be something wrong with how you are removing the data. If you could add that piece of code then I can help you further.
sure, 1 minute.
i have added the same, but using react chrome extn i am sure the logic is working as i can see the data array in state after delete has happened.
0

You can use a built-in set function provided by react with state. See below for an example:

import { useState } from 'react';
const [data, setData ] = useState([]);
fetch('https://localhost:5001/getdata')
    .then((response) => response.json())
    .then((data) => setData(data)) // Example setData usage
    .catch((error) => alert)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.