Reputation: 1894
Assume the following situation: As a logged-in user, you're accessing your own profile page. The header menu will show your avatar as a logged-in user, and the rest of the page will show your user public information.
You got a list of users from the api, and you need to handle data from 2 of these users: the logged-in user and the user which profile page is being accessed (in the situation above, it's actually the same user).
Duplicating the data in store.users
, store.currentUser
and store.myUser
would be a very bad idea (need to sync these 3 occurrences of the data everytime it gets modified). But I do not want my components using the current or logged in user data to be re-rendered everytime some lambda user data gets modified in the list of users.
How would you proceed in order to avoid data duplication, speed up data handling time (avoid costly list operations like filter/find), and avoid unnecessary re-rendering ?
After some thinking, I'm thinking of implementing it this way, Data are stored as follow:
store = {
users: {
1: {
name: 'John',
},
},
currentUser: 1, // user which profile page is being accessed
myUser: 1, // logged in user
};
Now, the UserDetails component can be connected as follow:
@connect(state => {user: state[state.currentUser]})
export default class UserDetails extends Component {
render() {
return <div>User profile: {this.props.user.name}</div>;
}
}
and the page header using the logged in user data can be connected as follow:
@connect(state => {user: state[state.myUser]})
export default class HeaderMenu extends Component {
render() {
return <div>Logged-in user: {this.props.user.name}</div>;
}
}
But I'm not convinced that this is an ideal solution. Will have to test whether the re-rendering is truly avoided or not. Your thoughts are very welcome!
Upvotes: 2
Views: 66
Reputation: 7189
I would store the details of the logged in user in the Redux store. Whatever data necessary to manage the user's session and render the persistent header. For other user profiles I'd load the data on-the-fly from the backend.
For example, if you had a route /profile/:id
and this was the URL foo.com/profile/99
class Profile extends Component {
constructor(props) {
super(props);
this.state = {
user: null,
loading: true
};
}
componentDidMount() {
api.get('/getUser', {userId: this.props.match.params.id}, response => {
this.setState({
user: response.user,
loading: false
});
});
}
render() {
return (
...
);
}
}
Upvotes: 1