简体   繁体   中英

What's the way to update dynamic state using React hooks?

I'm trying to update my code to React Hooks. My function is updating data inside async function after response. I've tried to do similar solution via React Hooks, but it doesn't really work. Why is that? What's the way to do it?

This is my update function:

updateData = (id, itemAttributes, property) => {
    let prop = this.state[property];
    let index = prop.rows.findIndex(x => x.eventID === id);
    if (index === -1) {
        return null
    } else
      this.setState({
          [property]: {
            columns: prop.columns,
            rows: [
                ...prop.rows.slice(0,index),
                Object.assign({}, prop.rows[index], itemAttributes),
                ...prop.rows.slice(index+1)
             ]
          }
      });
}

And that's the way I'm fetching data and using updateData func:

        this.state.data.rows.forEach((elem,index) => {
            setTimeout(async () => {
                const row = await axios.get(url);
                const elemInfo = {
                    eventRegistrants: row.data.numberOfRegistrants,
                    eventParticipants: row.data.numberOfParticipants
                }
                this.updateData(
                    elem.eventID, 
                    elemInfo,
                    'data'
                )
            }, index * 1000)
        })

EDIT

That's my current not working solution using React Hooks:

const updateData = (id, itemAttributes) => {
    let index = data.rows.findIndex(x => x.eventID === id);
    if (index === -1) {
        console.log('error');
    } else
        setData({
            columns: data.columns,
            rows: [
                ...data.rows.slice(0,index),
                Object.assign({}, data.rows[index], itemAttributes),
                ...data.rows.slice(index+1)
            ]
        });
}

Try using the functional form of setState :

const updateData = (id, itemAttributes) => {
  setData(currData => {
    const index = currData.rows.findIndex(x => x.eventID === id);
    if (index === -1) {
      console.log('error');
    } else {
      return {
        ...currData,
        rows: [
          ...data.rows.slice(0, index),
          Object.assign({}, data.rows[index], itemAttributes),
          ...data.rows.slice(index + 1)
        ]
      }
    }
  });
}

Another way is to set the state using map , which is more concise:

const updateData1 = (id, itemAttributes) => {
  setData(currData => {
    return {
      ...currData,
      rows: currData.rows.map(row => {
        if (row.eventID === id) {
          return {
            ...row,
            itemAttributes
          }
        }
        return row
      })
    }
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM