Reputation: 35
I've managed to get the users information using axios request. I've also managed to render users info on a view using a component that i created. My problem is that i cant display it on an another component i have created which is called ProfileForm. ProfileForm is used as form for updating the info of the user. I want to set the state on the constractor with the user info.
Also, when i change the values to this.props.user.username etc.. i receive two errors:
Warning: Failed prop type: The prop
value
is marked as required inTextFieldGroup
, but its value isundefined
. in TextFieldGroup (at ProfileForm.js:112) in ProfileForm (at ProfilePage.js:23)
and the second is
warning.js:36 Warning: TextFieldGroup is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
class ProfileForm extends React.Component
constructor(props) {
super(props);
this.state = {
username: '',
email: '',
password: '',
passwordConfirmation: '',
errors: {},
isLoading: false,
invalid: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
render() {
const { errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<TextFieldGroup
error={errors.username}
placeholder="Username"
onChange={this.handleChange}
value={user.username} <-- Here should be the bind
field="username"
/>
<TextFieldGroup
error={errors.email}
placeholder="Email"
onChange={this.handleChange}
checkUserExists={this.checkUserExists}
value={user.email} <-- Here should be the bind
field="email"
/>
<TextFieldGroup
error={errors.password}
placeholder="Password"
onChange={this.handleChange}
value={user.password} <-- Here should be the bind
field="password"
/>
<div className="form-group">
<button disabled={this.state.isLoading || this.state.invalid} className="btn btn-primary btn-md btn-block">Update</button>
</div>
</form>
);
}
}
export default ProfileForm;
Here is my ProfilePage
class ProfilePage extends React.Component {
componentDidMount() {
this.props.getUser();
}
render() {
const { profileUpdateRequest, addFlashMessage, getUser, isUserExists } = this.props;
return (
<div className="row">
<div className="row text-center">
<UserProfile user={this.props.user} /> <-- This works!!!!
</div>
<ProfileForm
profileUpdateRequest={profileUpdateRequest}
addFlashMessage={addFlashMessage}
getUser={getUser}
user={this.props.user} <--- This doesnt work!!!!
isUserExists={isUserExists}
/>
</div>
);
}
}
and my UserProfile which works
export default function UserProfile({ user }) {
const userProfile = (
<div className="row">
{user.username} {user.email}
</div>
);
return (
<div>
{userProfile}
</div>
);
}
My ProfileUpdateAction action
export function getUser() {
return dispatch => {
return axios.get('/api/user')
.then(res => res.data)
.then(data => dispatch(setUser(data.user)));
}
}
And my reducer
import { SET_USER } from '../actions/profileUpdateActions';
export default function user(state = [], action = {}) {
switch(action.type) {
case SET_USER:
return action.user;
default: return state;
}
}
My textFieldGroup
const TextFieldGroup = ({ field, value, label, error, type, onChange, placeholder, min, checkUserExists, disabled }) => {
return (
<div className={classnames("form-group", {'has-error': error})}>
<label className="control-label">{label}</label>
<input
type={type}
name={field}
className="form-control"
value={value}
min={min}
onChange={onChange}
onBlur={checkUserExists}
placeholder={placeholder}
disabled={disabled}
/>
{error && <span className="help-block">{error}</span>}
</div>
);
}
TextFieldGroup.propTypes = {
field: React.PropTypes.string.isRequired,
value: React.PropTypes.string.isRequired,
label: React.PropTypes.string,
error: React.PropTypes.string,
min: React.PropTypes.string,
disabled: React.PropTypes.bool,
placeholder: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
checkUserExists: React.PropTypes.func
}
TextFieldGroup.defaultProps = {
type: 'text'
}
export default TextFieldGroup;
Upvotes: 0
Views: 370
Reputation: 2206
In UserProfile, you're using a stateless component that is passed in props as an argument. In the function params, you destructure user to be its own constant. Thats cool and works well.
However, in UserForm, you have a class-based component. The props object is attached to the object's context (this). So to access it, you need to use this.props.user
.
Upvotes: 1