0

So im working on a pretty simple personal project to learn react. The state within my "SensorTable" component (Which is essentially just a react-bootstrap table currently that has a listing of my sensors (Which have values like id/temp/humidity/etc...).

Right now this components state is just an array of objects (That being my sensors) that I retrieve via axios/fetch from a GET request to JSON API that has all these objects. The GET request is made on componentDidMount.

Im really not fully comfortable with redux at this point, and this is simply a small toy app to get acquainted with React. But would I be correct in guessing the correct way to sort/filter this table would be to have a function that:

  • Retrieves the latest data from the API (Maybe?)
  • Updates the state either by sorting the array of objects in a specific order OR filtering them based off whatever filter type I want to use (Maybe filter by sensors that have a specific object key that is above or below or certain value). And then returns the new array to that state?

This sounds simple in theory to me...but wouldn't the componentDidMount just fire again once this function happens (resetting the data to how it was originally?). Or is there a way to make it NOT re-fire that method if I update the state in one of these filter/sorting functions?

0

3 Answers 3

3

componentDidMount only fires when the component is initialized and not on further renders, so your request will only fire once until you unmount and remount the component (by navigating away from and returning to the page, for example).

As for updating state, let's say you store the response data in a state variable called sensorData. If you set sensorData every time the user applies a filter, you are losing data, because you are effectively removing items from the sensorData array. This means that when the filter is removed, a refetch is required to regain the data you filtered out.

A better approach would be to store all the response data in sensorData, and apply the filter inline when rendering the table.

For example:

{sensorData.filter(d => d.someProp === "someVal").map(d => <TableRowItem />)}

This way, when removing the filter, you do not have to hit the server again and the UI is updated immediately.

Sign up to request clarification or add additional context in comments.

4 Comments

Ah good point, since otherwise I would need to re-GET all the data again. What is d => d.someProp === "someval" in this case?
I guess a good idea would be to keep the "filter/sort" kept as a state value and then based on that state value filter the table based on it.
Yeah so you would keep the value that you filter and sort by in state.
d => d.someProp === "someVal" is just an example of a filter. In your case, if you had some data and each data item had a property "name", and you wanted to filter all items where the item name contained a certain string (let's say that this string is stored in a state variable "filterNameString", then you would say "find me all the items where the name contains this string", in code this would be: sensorData.filter(d => d.name.includes(filterNameString)). The filter function is just like a forEach or map function, but only returns an array of items that match the filter.
2

In the simplest component case, yes, make API calls (or any number of side-effects) in the componentDidMount lifecycle function. componentDidMount is called only once when the component is mounted. componentDidUpdate however, is called upon any changes to state or props.

A sample component could look like this:

class MyComponent extends Component {
  this.state = {
    data: [];
  };

  componentDidMount() {
    getDataFromAPI().then(
      response => setState({
        data: response.data.filter(someFilterFn) // filter result array and store in state
      });
    );
  }

  render() {
    <div>
      {this.state.data.map(mapElementFn)}
    </div>
  }
}

This is just an example, you could also just store all the data in state and filter (as needed) in the render function. It's really up to you and your app's needs.

2 Comments

I guess the issue with doing the above, if for instance I had a filter button or something on my table, I would need to filter elsewhere since componentDidMount() only gets called once like you said (Otherwise i'd need a full page refresh or something right?)
Yes, the above assumes you fetch once and filter. If you fetch on-demand, or change what you filter by after mounting then you'd want to separate it out.
1

componentDidMount triggers only ones.

Using state, you can maintain two keys one with intialList and modifiedList after filter / sort. Local sort is based on normal js array sort. ref : https://moduscreate.com/blog/ext-js-to-react-load-sort-and-filter-data-with-react/

You can filter in your local or rely on remote thing

When you use remote api calls to sort, then you need to use an event handler and invoke the fetch call explicity.

Ref: https://codereviewvideos.com/course/pagination-filtering-and-sorting/video/react-sorting Ref: Sample https://github.com/codereviewvideos/react-symfony-3.example/blob/pagination-sort-filter/src/containers/list.js

Same applies for filter as well.

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.