I have a list of items.
I render a Table component with this list.
I want to add a checkbox for each row.
Do I have to use a separate component for the table row iteself in order to set the current row style by checking it without rendering the whole table?
Becasase now when I change the item's 'selected' property, the whole table is rendering.
Thanks :)
If your whole table re-render, you should clearly update your code to avoid that. Like you said, you can have a component for each row, so when a row update, only the row re-render. I'm strongly suggesting you to do this. Be sure to include a key prop to each row to avoid performance leak. You can also use the shouldComponentUpdate method to avoid useless re-render. When passing your props down from the table component to the row component, make sure the objects your are passing are unique on don't change too often. If after all this, you realised you row will update and re-render often, you can try using react-virtualized, this library renders only the rows that are visible on the screen. If you need more help, you can also share some code.
Related
I have a table implemented in material table and it has served its purpose, unfortunately due to the poor performance issue where it re-renders every time there is a change in the state regardless of the states connection to the table itself.
I've opted to move to a different table and looking at React table as a possibility.
Can react table rows be customized that's not inline with the column data fully like the table below?
The parent has a different data compared to the sub-parent and the data in the sub-parent is different from its own parent (Which is the sub-parent).
To answer my own question.
Yes, react-table can certainly do these, you just need to conditionally render each row and table differently.
I have an application that shows and manipulates users' information in a table with many columns. The user model has quite a few deep nested properties, each table column represent a property. To better explain, I created this simplified app at stackbliz. The real application has more columns and is relatively organised into more layers/components.
Basically, each column is a component that has an #Input person. While Location property value is changed by clicking itself, another component LOS needs to be aware of it and change its text colour, if location becomes 'J'.
Normally, this isn't working as the person reference of each #Input is not changed, so the change detection is not firing.
Please ignore the pipe used as it's just a way to show one component has to react if a property is changed in another component. I can mark it as impure but it seems not a good way as it will run too many times unnecessarily.
Also, I know I can make it work by using getter or a function to read the property in another component template, I have included the code as comment in stackblitz app. But it can unnecessarily run many times as well.
Question
I wonder if there is another better, cleaner and intuitive way to notify nested property changes between components. It could be a better way of organising the object and its property, passing them to different components, or other techniques that don't bring performance overheads.
Thanks in advance
Component Structure
You need a a RowComponent to segregate each row and its data and coloring of the LOS column (which may differ between rows).
After adding this component, I would not use LocationComponent or LengthofstayComponent as there is not much to them and your code will become cluttered with passing values between them.
Implementing the color changing
I recommend using a BehaviorSubject, a corresponding Observable and the async pipe. Every time the async pipe, emits, a change detection cycle will be intiated.
In RowComponent add:
showColorSubject = new BehaviorSubject<boolean>(false);
showColor$ = this.showColorSubject.asObservable();
If we call next on the Subject in changeLocation:
this.showColorSubject.next(this.person.location.code === "J");
then showColor$ will emit true/false accordingly in the RowComponent template where we use the async pipe to selectively enable the color class:
[class.color]="showColor$ | async"
Stackblitz
https://stackblitz.com/edit/so-color-row-cell?file=src%2Fapp%2Frow%2Frow.component.html
(Formatting is messed up but I'll leave that to you)
I use vuex for state management. Let's say i Have n components using the vuex to access the data. All the n components are using the state and have bound to the view. So I want to know if component1 changes the state, let's say remove a particular element, how can I trigger the the n-1 components to update the view with the regarding state. Can it done with the computed function or is there an other more efficient way to update the views with the correspondent state.
Kind regards.
using computed
as you mentioned the clean way is to use computed property. within the functions you can access this.$store.state and change the behaviour of component n+1 depending on n.
including changes in action
another way would be that your action simply triggers mutations for element n and n+1.
styling related changes
just to mention it, when you want a component to be conditionally displayed or styled, it is often enough to set a class on the modified component n and using conditional styling based on this class to style n+1.
I am developing a react JS component with JSX coding structure that gets a JSON array of data from api. The component is a table like structure and has two arrows at the top and bottom. I want to achieve a functionality where on click of top arrow the table rows should be updated with new set of data in rows and vice-versa happens on click of down arrow. Is there a way to achieve this functionality?
It seems you are trying to do some sort of table paging. You can do this by storing the current page on the state of your control, and on the onClick handler:
make the call to the server API to retrieve the data for the next/previous page if you are paging and sorting on the server, then update the state with the retrieved data
or calculate and update the state with whichever rows you want to display if you already have all rows in memory but are showing a small set of them
I've a list (immutable.js) in my store containing multiple objects.
This list is displayed in a component as a table with rows. Those rows are subcomponents displaying one single object. One attribute of those objects should be editable. So onChange() i dispatch an action which should change the attribute of that one specific object. As we should never ever change the state, i return a whole new list with just that single object changed. But because the whole list is a new list object, the table component gets updated every single change. this leads to a really slow working app.
I've just looked at the official todo app example and inspected it with the Perf addon. Realising that they also rerender the whole todos-list on every change (mark as completed, unmark). How am I supposed to fix that?
The biggest factors that will impact your list rendering performance are heavy rendering cycles and expensive DOM mutations. Make sure that your list items are as efficient as possible when they re-render. Done properly, this will make a big difference.
You have a couple of straight forward options.
Break your rows out into their own component (if not already done) and optimize the render and update cycle.
Use a library such as react-virtualized to help with list/table/grid performance.