I am new to React-Redux and I have a problem with one of my redux action objects. When I print my function this.handleUserByID(1) @KeyboardPage.jsx to console everything gets called multiple times and I recieve this error:
But I still get the right result in the console at some point:
[
Here my Code:
KeyboardPage.jsx
class KeyboardPage extends React.Component {
componentDidMount() {
this.props.getTopics(2);
}
handleUserByID(user_id){
return this.props.getUser(user_id);
}
render() {
const { topics } = this.props;
const { user, users} = this.props;
console.log(this.handleUserByID(1));
return (
<div className="container">
<NavBar loggedinAs={user.user_name}/>
<h1>Gruppe 1 - Webforum</h1>
<h3>Topics :</h3>
{topics.loading && <em>Loading topics...</em>}
{topics.error && <span className="text-danger">ERROR: {topics.error}</span>}
{topics.items && users.items &&
<ul type='none' >
{topics.items.map((topic, index) =>
<li key={topic.topic_id}>
<p/>
<a href={"/" + topic.topic_id} style={{ textDecoration: 'none' }}>
<TopicCard topicSubject={topic.topic_subject} topicDate={topic.topic_date} topicBy={this.handleUserByID(topic.topic_by).user_name}/>
</a>
</li>
)}
</ul>
}
</div>
);
}
}
function mapState(state) {
const {topics } = state;
const { users, authentication } = state;
const { user, } = authentication;
return { user, users, topics};
}
const actionCreators = {
getTopics: topicActions.getAllbyID,
getUser: userActions.getById
}
const connectedKeyboardPage = connect(mapState, actionCreators)(KeyboardPage);
export { connectedKeyboardPage as KeyboardPage };
users.reducer.js
export function users(state = {}, action) {
switch (action.type) {
case userConstants.GETBYID_REQUEST:
return {
loading: true, id : action.id
};
case userConstants.GETBYID_SUCCESS:
return {
item: action.user
};
case userConstants.GETBYID_FAILURE:
return {
error: action.error
};
default:
return state
}
}
user.service.js
function getById(id) {
const requestOptions = {
method: 'GET',
headers: authHeader()
};
return fetch(`${config.apiUrl}/users/${id}`, requestOptions).then(handleResponse);
}
user.actions.js
function getById(id) {
return dispatch => {
dispatch(request(id));
userService.getById(id)
.then(
user => dispatch(success(user)),
error => dispatch(failure(error.toString()))
);
};
function request(id) { return { type: userConstants.GETBYID_REQUEST, id} }
function success(user) { return { type: userConstants.GETBYID_SUCCESS, user } }
function failure(error) { return { type: userConstants.GETBYID_FAILURE, error } }
}
root reducer
import { combineReducers } from 'redux';
import { authentication } from './authentication.reducer';
import { registration } from './registration.reducer';
import { users } from './users.reducer';
import { categories } from './categories.reducer';
import { topics } from './topics.reducer';
import { alert } from './alert.reducer';
const rootReducer = combineReducers({
authentication,
registration,
users,
categories,
topics,
alert
});
export default rootReducer;
EDIT: I found a way to solve the problem. In my component KeyboardPage.jsx I already retrieved all the users. I I now simply filter the users directly according to the userId. Not the most elegant solution, but it works for now.
{topics.items && users.items &&
<ul type='none' >
{topics.items.map((topic, index) =>
<li key={topic.topic_id}>
<p/>
<a href={"/" + topic.topic_id} style={{ textDecoration: 'none' }}>
<TopicCard topicSubject={topic.topic_subject} topicDate={topic.topic_date} topicBy={users.items.filter(user => user.user_id === topic.topic_by)[0].user_name}/>
</a>
</li>
)}
</ul>
}