I have object (this is one property array and as it is dynamic I can't split it to multiple properties) that I keep in reducer that looks something like this:
[
{type: list, elements: []}
{type: map, elements: []}
{type: wheelList, elements: []}
{type: chart, elements: []}
{type: dyna, elements: []}
...
]
In one component I get it from store and access it like:
this.props.allElements
Then for each of it I render different component (pseudo code):
foreach (el in this.props.allElements) {
if (el == list) {
return <ListComponent elements={el.elements}>
}
if (el == map) {
return <MapComponent elements={el.elements}>
}
...
}
This way each component get only elements that is interested to.
My question is about performance and optimisation.
Is my approach any good?
I suffer some performance issues so checking if maybe my organisation
here is wrong and need advice if it can be improved.
I have some frequent updates sometimes map can be updated every second.
So if I update only map elements and pass it to action to update it will all this components run render again or just the one that watch map.
UPDATE
But to update map
elements I need to get whole this object
from store
in action update only map
elements and then pass whole updated object to reducer
.
So only map is changed others are not.
Is react/redux smart enough to update only component that data is changed (map in my case).
Action:
export function getScreenElements() : Action {
return function(dispatch) {
// get data from server here
// and do some calculations here
dispatch({
type: 'ELEMENTS_RECEIVED',
allElements: data
});
Reducer:
export default function (state:State = initialState, action:Action): State {
if (action.type === 'ELEMENTS_RECEIVED') {
return {
...state,
allElements: action.allElements,
};
In big component:
const mapStateToProps = state => ({
allElements: state.main.allElements
...
class Main extends Component {
...
componentDidMount() {
// here I actually make a call to get data
}
...
render() {
return (
// Here is the big code
// Loop over props.allElements
// and render it in different way based on data inside each element
)
}
Data example:
[
{
"type": "list",
"count": 99,
"elements": [
{
"id": 1,
"name": "test"
},
{
"id": 2,
"name": "test1"
}
]
},
{
"type": "map",
"count": 99,
"elements": [
{
"id": 3,
"name": "test"
},
{
"id": 4,
"name": "test1"
}
]
},
{
"type": "list",
"count": 99,
"elements": [
{
"id": 5,
"name": "test"
},
{
"id": 6,
"name": "test1"
}
]
},
{
"type": "list",
"count": 99,
"elements": [
{
"id": 7,
"name": "test"
},
{
"id": 8,
"name": "test1"
}
]
}
]
You can do the loop inside your thunk
action
and split the data into seperate reducers
.
You Action could look something like this:
// action thunk
export function getScreenElements() {
return function (dispatch) {
// get data from server here
const dataFromServer = fetch('url');
// do your looping here and dispatch each data acording to its type
dataFromServer.map(obj => {
switch (obj.type) {
case 'list':
dispatch({
type: 'LIST_RECEIVED',
listElements: obj
});
case 'map':
dispatch({
type: 'MAP_RECEIVED',
mapElements: obj
});
// ....
}
});
}
}
Your separate reducers could look something like this:
// map reducer
export default function map(state = initialState, action) {
if (action.type === 'MAP_RECEIVED') {
return {
...state,
mapElements: action.mapElements,
}
}
}
// list reducer
export default function list(state = initialState, action) {
if (action.type === 'LIST_RECEIVED') {
return {
...state,
listElements: action.listElements,
}
}
}
And then you can render it like this:
// inside your component render mehtod
render(){
const { list, map } = this.props; // redux data passed as props from the seperate reducers
return (
<div>
<ListComponent elements={list}>
<MapComponent elements={map}>
</div>
);
}
Edit
As a followup to your comment:
If I put allData to parent and pass allData.xyz to component in render when any data change parent will also reRender as it’s props is changed
Well, there is nothing wrong with Parent being re-rendered. when the render
method of component
runs it doesn't mean it will re-render to the physical DOM
,It will update or override the object of the virtual DOM
and then will check for differences between the physical and virtual DOM
via the Reconciliation and The Diffing Algorithm to determine when, how and where should the physical DOM
get updated.
It can update only certain attributes of DOM
elements without re-render them, React Only Updates What’s Necessary.
There is also the option of React.PureComponent but i strongly advice against that in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With