简体   繁体   中英

how to limit the length my array in state that holds the messages I'm getting from my data in React

So I'm using a pub/sub model that listens to published message from another client as they are sending in real-time, and I'm storing those messages on my component's state object as an array, and I keep adding them as they come in. I'm displaying the data in a chart but I was wondering how I could limit the amount of messages that state stores, say to maybe like 50? was thinking about using sliceshould i be mutating state to remove items also?

should I put an if condition in my ComponentDidMount method that checks state like this?

  if(this.state.data.length > 50) {
    this.setState({ data: this.state.slice(-50) })
  }

Just trying to see what a good approach would be to limiting the number of message so state doesn't have like 50,000 objects in it. Thanks

Edit:

Per Asymons comment, I changed it to look like this. And thank you so much your comment was so helpful. I just have one more question re: the last part you mentionned about reducing re-renders. Does this code satisfy that part, because I am very much concerned about performance so I would like to reduce re-renders as much as possible, thanks again.

componentDidMount() {

client.on('message', (topic, payload, packet) => {
  console.log('topic: ', topic);

  const parsedPayload = JSON.parse(payload);
  if (parsedPayload.type !== 'pub') {
    return null;
  }
  const voltage = Math.trunc(parsedPayload.data.data.voltage);
  const pressure = Math.trunc(parsedPayload.data.data.air_pressure);
  const humidity = Math.trunc(parsedPayload.data.data.air_humidity);
  const temperature = Math.trunc(parsedPayload.data.data.air_temperature);
  const message = {
    time: moment().format('LT'),
    temperature,
    humidity,
    voltage,
    pressure,
    parsedPayload,
    topic,
  }
  this.setState((prevState) => {
    // create an array that holds objects with my data and push the 
    // message object as it comes in into the array
    const messages = [...prevState.messages]
    messages.push(message)
    if (prevState.messages.length > 20) {
      messages.pop()
      return {
        messages,
      };
    } else {
        return {
          messages,
        };
    }
  });
});

}

You need to target where the data comes in from.

So in your componentDidMount wherever your network request is, you either request the amount of data (look into pagination) or get the whole payload and filter the data as it comes in. So in your case, filter it initially.

You said you're doing a pub/sub model so you'll have some data trickling in, that's fine. Shift your focus from slicing the whole thing to treating the data structure as a queue. Push items in and pop them when the size is above 50 or whatever your limit is. So the data would go into the state like a pipeline.

In order to reduce re-renders, copy your this.state.data into some variable, mutate that variable and then update the state with that mutated variable.

Let me know if this works for you.

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