My Application and Store
Using Redux with ReactJS, I am keeping an array of objects (called results) in the store and dispatching actions that sort and manipulate it. In mapStateToProps, I return this results array, which renders the results in a list on the view.
// in Component file
export default class ResultList extends Component {
constructor(props) {
super(props);
this.renderResults = this.renderResults.bind(this);
}
renderResults(results) {
return (
results.map((result) => {
return <AnotherComponent />
})
);
}
render() {
const { results } = this.props;
return (
<div>
<ul>
{this.renderResults(results)}
</ul>
</div>
)
// in Container Component file
const mapStateToProps = (state, ownProps) => {
console.log('map state is triggered');
return {
results: state.results
};
}
The Problem
I have found that although my mapStateToProps successfully triggers to update the props to my class component, for some reason the view only updates on the FIRST time that the results array gets manipulated, but does not update on future updates to the store. (Please see update below. This is not entirely accurate.)
I have made sure that this problem is not due to mutating state in my reducers as is often the case; I have confirmed that the mapStateToProps runs every time that the store gets updated (as indicated by the console.log). The problem seems to be between the results props getting returned from mapStateToProps and the view actually rendering the results array, but I do not have visibility to see what Redux is doing under the hood.
The closest problem that someone else has had to what I am experiencing seems to be this, but I do not know how or if this fix applies to my use of a stored array: https://forums.meteor.com/t/the-state-is-correctly-mutated-and-returned-but-view-does-not-rerender/28840/5
Any help would be greatly appreciated. Thank you.
Update
I apologize, but must correct my statement above saying that there are no further updates to the view after the first time the results in the store gets updated. With further testing I have found that is not completely true. The view gets updated only when the results array is sorted according to case 1 of the below sorting function. Cases 2 and 3 are the ones that result in no update to the view. This may/may not be necessary information, but the results array gets sorted by these 3 cases in a cycle onClick in the following order: case 1, case 3, case 2.
// in reducer index.js file
case SORT_RESULTS:
return {
...state,
results: sortArr(state.results, state.sortType)
};
// sorting function
function sortArr(arr, sortType) {
let newArr = [];
switch (sortType) {
case '1':
for (let i = arr.length - 1; i >= 0; i--) {
newArr.push(arr[i]);
}
return newArr;
case '2':
newArr = arr;
newArr.sort((a, b) => {
return b.num - a.num;
});
return newArr;
case '3':
newArr = arr;
newArr.sort((a, b) => {
let id1 = a.id.toLowerCase();
let id2 = b.id.toLowerCase();
if (id1 < id2) {
return -1;
}
if (id1 > id2) {
return 1;
}
return 0;
});
return newArr;
default:
return arr;
}
}
state.results
inmapStateToProps
? – Andrew LicomponentWillRecieveProps(nextProps) { console.log(nextProps.results)
and see if the props are getting updated there? – Grandas