This React-Redux code was used to load more content from database each time Loadmore button was clicked and it work fine.
Initial content display was 2 and as you click on loadmore button, more records gets loaded in two's.
I Later find out that each time I click Load more button and more content gets loaded, as I logout and login again those records that was loaded on button click will still be on the Page and therefore causing records display (id) conflicts which results in the following error below
bundle.js:856 Warning: Encountered two children with the same key, 1
. Keys should be unique so that components maintain
their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior
is unsupported and could change in a future version.
Please how do I prevent this records display conflicts...
I think what causes this issue is the concatenation of the old/default records with newly loaded records via loadmore button in my user.reducer.js i have the code below
//concatenate the old item with new item
case userConstants.GETALL_REQUEST:
return {
...state,
loading: true
};
case userConstants.GETALL_SUCCESS:
return {
loading: false,
error: null,
// items: action.users
items: [ ...(state.items || []), ...action.users ]
};
here is the homepage components
import React from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { userActions } from "../_actions";
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
row_pass: 0
};
this.row = 0;
this.rowperpage = 2;
this.buttonText = "Load More";
this.loadMore = this.loadMore.bind(this);
}
componentDidMount() {
this.props.dispatch(userActions.getAll(this.row));
}
loadMore() {
this.row += this.rowperpage;
alert("loading" + this.row);
this.props.dispatch(userActions.getAll(this.row));
this.buttonText = "Load More";
}
render() {
const { user, users } = this.props;
return (
<div
style={{ background: "red" }}
className="well col-md-6 col-md-offset-3"
>
<h1>
Hi{user.message}! {user.token}
</h1>
<p>You're logged in with React!!</p>
<h3>All registered users:</h3>
{users.loading && <em>Loading users...</em>}
{users.error && (
<span className="text-danger">ERROR: {users.error}</span>
)}
{users.items && (
<ul>
{users.items.map((user, index) => (
<li key={user.id}>
{user.firstName + " " + user.lastName}:
<span>
{" "}
- <a>home</a>
</span>
</li>
))}
{this.finished}
</ul>
)}
<p>
<a className="pic" onClick={this.loadMore}>
{this.buttonText}
</a>
</p>
</div>
);
}
}
function mapStateToProps(state) {
const { users, authentication } = state;
const { user } = authentication;
return {
user,
users
};
}
const connectedHomePage = connect(mapStateToProps)(HomePage);
export { connectedHomePage as HomePage };
here is user.action.js
function getAll(row) {
return dispatch => {
dispatch(request(row));
userService.getAll(row)
.then(
users => dispatch(success(users)),
error => dispatch(failure(error.toString()))
);
};
user.reducer.js code
import { userConstants } from '../_constants';
export function users(state = {}, action) {
switch (action.type) {
//concatenate the old item with new item
case userConstants.GETALL_REQUEST:
return {
...state,
loading: true
};
case userConstants.GETALL_SUCCESS:
return {
loading: false,
error: null,
// items: action.users
items: [ ...(state.items || []), ...action.users ]
};
case userConstants.GETALL_FAILURE:
return {
error: action.error
};
default:
return state
}
}