React setState slow - javascript

so I was programming an app with React and what happened is that I have a component with a fairly large list in its state. I am fetching a JSON file from network and then storing a filtered copy directly to component's state. Might be unoptimal solution BUT I think that's still okay and React should handle it I mean, it's just 10 kB.
Anyway I decided to add a search input to my component and store its value to its state. Now I have both the large list and searchInput in its state which I am setStating every onChange and filtering the list based on that.
And that is super slow. Every setState is refreshing the list and doing componentUpdates on every children and subchildren of the component which basically makes the search unusable.
So my question is how to fix this issue? Should I store the filtered list in the redux store instead of local component state? That doesn't seem that good a solution either as I have now a global searchInput value which I have to reset and delete on leave and which I think is better as local value.
Here's how it's currently:
list -> component -> filter list -> child -> split the list into 4 -> subchild -> map the sublist -> render the list item values
What I thought too was adding additional list with values showing which items should be hidden/shown so instead of manipulating the large list I am manipulating smaller list of item ids. Still that seems a bit silly, this thing shouldn't be this hard I mean people have been doing lists with JS and HTML quite a while now. I was thinking about re-creating the same component with Vue just to see would it be better (which I think it would).

I see your problem. It's not actually the setState that is slow but actually the rendering and the way you search things in said state.
If I were you I would invest time in 2 things:
debounce for the searching
debounce doesn't trigger the search immediately but "waits" a set amount of time for the user to stop typing and then it triggers the function.
Here's an example in React:
// you can use another one. I've just used this one before and it works
import debounce from "throttle-debounce";
class SearchBox extends React.Component {
constructor(props) {
super(props);
// "waits" for 750 ms
this.search = debounce(this.search, 750);
}
search() { ... }
render() {
<input type="text" onKeyUp={this.search} />
}
}
If you have a big list then memoization is a good bet. You can use react-virtualized for that.
React components for efficiently rendering large lists and tabular
data
You can even access the List demo here
A good UI design and pagination
react-virtualized List component will only render what is being seen by the user. So if you have a nice UI design you can juice up a lot of performance from a really big list of values.
Many times it comes down to how you display data to your end-users. So you can add pagination to your data and fetch more either with pagination links or a infinite scroll feature.
Hope I helped

Related

Prevent Vue.js re-rendering child components

I've got a complex component which does all its rendering in a render function. There are multiple parts to this, and different bits of the view get rendered - one of these things is a filter bar, showing the filters that have been applied.
What I'm noticing happening, is if I apply a filter which in turn presents this bar, it causes everything else to be fully re-rendered. This is causing a number of other issues and I need to try and stop it from happening.
I've never come across this issue when using normal templates as Vue seems to handle these very intelligently, but I have no idea how to tackle this. The only thing I can think of is setting a key on each thing I don't want re-rendered but not sure if this will a) solve the problem, and b) be possible for the content that is passed in through a slot
Has anyone else faced this issue, and if so how can it be solved?
I had a similar issue when using vuetify text inputs in a complex component which was causing the app to slow down drastically.
In my search I found this link which was specific to vuetify:
high performance impact when using a lot of v-text-field
then found out that this is actually a vue thing from this GitHub issue:
Component with slot re-renders even if the slot or component data has not changed
and there is plan to improve this in it is tracked here (vue 3 should resolve this issue):
Update slot content without re-rendering rest of component
so after reading through all these I found some workarounds that helped me a lot to boost the performance of my app, I hope these will help you as well:
divide that complex component into smaller ones specially when there is some bit of code that changes data that bounds to template causing re-rendering (put them in their own component)
I moved all data layer control to the vuex store, instead of using v-model every where and passing data as events and props, all the data is updating in the store through an action and read from the store through a getter. (from data I mean somethings that is being looped in the template in a v-for, API results, and so on... all of them is being set, updated and read through the store. my components still have the data object but only for the things related to the style and template control like a boolean to control a modal or an imported icon which is used in the template and alikes)
lastly I wrote a function called lazyCaller which its job is to update the values in the store with a delay (when immediate data update isn't necessary) to avoid rapid updates comping from something like a text input (with out this every key stroke trigger the value update action)

React Having Two classes with Two sets of state

I am new to React. I have a small app I'm designing with a schedule and with list of products. Please see my component diagram, below.
I propose that The Schedule Controller and Product Control each will be a class with state.
I brought all the Product modules (a listing component and its children, A new product form, a product detail module, and an edit product module) to be direct children of the Product Controller to prevent excess prop drilling, so they can all pull from the product control class state.
So, as I'm thinking about this, I'm mindful of a single source of truth and to concentrate a single state. However, I've always done that because the whole app has one class.
It seems to me that, to obey those laws (and without using a store as in Redux, which I'm not ready to work my way up to yet. This is a learning exercise and I want to get some proficiency with regular React before adding a whole new library to my learning) I should pick the highest parent component and make only one class with one state.
It seems to me that when I use setState(), its going to the use the state of the class it inherits from. Right? And that state isn't going to get confused about which state to use, because its going to the parent class (I'm totally out on a limb here). The product modules will be extended from the Product class and setState() will only go up the chain to the parent and the parent state.
Or is the correct approach to squash the schedule modules as children of the product controller?
I did a lot of looking around and the references I keep finding are much more complex than what I'm attempting here (involving two different classes with state that DO share information, that's not happening here). I may not be searching the correct terms. So I'm sorry if this is something well known.
So the question I have is, is this a bad idea or bad practice?
A setState call in a class Component only sets the state of itself.
There are two forms of class state
State-> This will be the local state of the class. It will be changed and maintained by the class which declares it.
Props-> These are states/properties which are passed from the parent to the child class. This value cannot the changed. Only the parent class which owns these props has the power to change it. The only way to change this would be through lifting the state. You are right here.
Refer https://reactjs.org/docs/lifting-state-up.html
marzelin had the answer in the comments above. Thanks!

Two components binding Vuejs

How would be perfect to organize data and interaction between two vuejs components? For example:
1) i have one component
item(v-for="item in items)
a {{item.name}}
2) and the second
card(v-for="item in items")
div.content
img {{item.photo}}
div {{item.desc}}
button Details
The main idea is when i click on list item i want to toggle the card with the same id, as list has. I use one file conponent management from vue webpack template.
A lot of folk seem to be trying to use Vue without a store. Could you be one of them? Perhaps because the store is not strictly part of Vue? Perhaps because the docs spend more time on parent-child communication, events etc (complicated) than on state management (simple)? Perhaps because OO has rotted our brains?
Vue wants to talk to a store. The whole point of bidirectional binding is to separate state from markup. The whole reason why this is such a genius idea is that many (most?) items of state have more than one representation on screen, like your items array. Your store, which can be as simple as a js object in window scope, should contain all your page state at a given moment. You should be able to copy-paste the store between pages, and be looking at the same thing on screen. The important qualities of a store are...
that there's only one of them.
that you 'normalize' your store so that an item of state is only stored once, and there are minimal dependencies between items of state.
Your items array should be in the store, and both components refer to this 'single source of truth'. If you're using other people's components, then you'll need to feed them some properties, but properties are for creating tunnels through Vue components to link leaf components with your store. Your items are your state, and state shouldn't generally live in Vue stuff. Does that help?

Does React Native Flatlist re-render upon deletion/insertion/change?

This might seem like a dumb question, but I just spent a bunch of hours making a List that I now have to add onUpdate onDelete onInsert functions for, and apparently FlatList will just check through my data array (provided I extract a key from each item and re-render accordingly. On top of that it apparently provides virtualization.
So my question is, if I use a keyExtractor and a unique part of my item (say, a user ID) can I dodge writing onUpdate onDelete onInsert and just rely on FlatList doing that part for me?
And if I wanted to sync data every 15 seconds, the user would not see a big re-render of the entire list, right?

React recursive components - Children not rerendering properly

I'm writing a series of components in react that will make a structure like this:
Field
|_BasicField: plain input field.
|_ListField: a list of Fields.
|_Entity: a complex Field that can have BasicFields, ListFields
and Entities as its children components.
The code for this structure you can find it here in my repo.
The data used to generate the scraping form is in this file.
What happens is that once the first level of the form is rendered, children Fields are dynamically generated, but they don't seem to be rerendering as expected. I'm just trying to make sense out of it, and it seems to me that react had the children components cached in a previous state, but when the state updates it doesn't update the children components, but renders them as they where in the previous state, or something like that, I'm really lost here. I don't even know where to look for the error. Please any help will be really appreciated! Thanks.

Categories