Let’s build a simple user profile page with some user attributes.
Create src/pages/Profile.jsx
, then add to <Navigator>
Modify src/components/Navigator.jsx
const ProfileItems = props => (
<React.Fragment>
<Nav.ItemLink href="#/">
Home
</Nav.ItemLink>
<Nav.ItemLink href="#/profile" active>
Profile
</Nav.ItemLink>
<Nav.ItemLink href="#/login">
Login
<BSpan srOnly>(current}</BSpan>
</Nav.ItemLink>
</React.Fragment>
)
...
render() {
...
<Route exact path="/profile" component={ProfileItems} />
...
}
Add to <Main>
<Route
exact
path="/profile"
render={(props) => <Profile user={user} />}
/>
We call Auth.userAttributes
to load attributes. user
is a property of <Profile>
component. It may change after mount, so we need to listen to componentDidUpdate
as well as componentDidMount
componentDidMount() {
if (this.props.user) { this.loadProfile() }
}
componentDidUpdate(prevProps) {
if (!prevProps.user && this.props.user) {
this.loadProfile();
}
}
loadProfile() {
const { user } = this.props;
Auth.userAttributes(user)
.then(data => this.loadSuccess(data))
.catch(err => this.handleError(err));
}
loadSuccess(data) {
logger.info('loaded user attributes', data);
const profile = this.translateAttributes(data);
this.setState({ profile: profile });
}
handleError(error) {
logger.info('load / save user attributes error', error);
this.setState({ error: error.message || error });
}
translateAttributes(data) {
const profile = {};
data
.filter(attr => ['given_name', 'family_name'].includes(attr.Name))
.forEach(attr => profile[attr.Name] = attr.Value);
return profile;
}
render
the component
render() {
const { profile, error } = this.state;
return (
<Container display="flex" flex="column" alignItems="center">
<InputGroup mb="3" style=>
<InputGroup.PrependText>First name</InputGroup.PrependText>
<Form.Input
type="text"
defaultValue={profile.given_name}
onChange={event => this.handleInputChange('given_name', event.target.value)}
/>
</InputGroup>
<InputGroup mb="3" style=>
<InputGroup.PrependText>Last name</InputGroup.PrependText>
<Form.Input
type="text"
defaultValue={profile.family_name}
onChange={event => this.handleInputChange('family_name', event.target.value)}
/>
</InputGroup>
<Button primary px="5" onClick={this.saveProfile}>Save</Button>
{ error && <Alert warning>{error}</Alert> }
</Container>
)
}
To keep simple we just cover ‘given_name’ and ‘family_name’, which are in ‘standard attributes’ list from Cognito: Configuring User Pool Attributes
For saving, we call Auth.updateUserAttributes
saveProfile() {
const { user } = this.props;
if (!user) {
this.handleError('No user to save to');
return;
}
Auth.updateUserAttributes(user, this.state.profile)
.then(data => this.saveSuccess(data))
.catch(err => this.handleError(err));
}
npm start