javascript - 如何使用用户信息渲染表单(React + Redux)

标签 javascript reactjs react-redux

我已成功使用 axios 请求获取用户信息。我还设法使用我创建的组件在 View 上呈现用户信息。我的问题是我无法在我创建的另一个名为 ProfileForm 的组件上显示它。 ProfileForm用作更新用户信息的表单。我想使用用户信息设置承包商的状态。

此外,当我将值更改为 this.props.user.username 等时。我收到两个错误:

Warning: Failed prop type: The prop value is marked as required in TextFieldGroup, but its value is undefined. in TextFieldGroup (at ProfileForm.js:112) in ProfileForm (at ProfilePage.js:23)

第二个是

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;

这是我的个人资料页

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>
        );
      }
    }

和我的用户配置文件有效

export default function UserProfile({ user }) {

  const userProfile = (
    <div className="row">
      {user.username} {user.email}
    </div>
  );

  return (
    <div>
      {userProfile}
    </div>
  );
}

我的 ProfileUpdateAction 操作

export function getUser() {
  return dispatch => {
    return axios.get('/api/user')
    .then(res => res.data)
    .then(data => dispatch(setUser(data.user)));
  }
}

还有我的 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;
  }
}

我的文本字段组

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;

最佳答案

在 UserProfile 中,您使用的是在 props 中作为参数传递的无状态组件。在函数 params 中,您将 user 解构为它自己的常量。这很酷并且效果很好。

但是,在 UserForm 中,您有一个基于类的组件。 props 对象附加到对象的上下文 (this)。因此要访问它,您需要使用 this.props.user

关于javascript - 如何使用用户信息渲染表单(React + Redux),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43618984/

相关文章:

javascript - 如果我更改设备时间,如何获取实际的世界时间?

javascript - node.js 支持什么版本的 Javascript

javascript - React jsx 第一个选项卡在切换后中断

javascript - Metro Bundler 遇到内部错误,请检查您的终端错误输出以获取更多详细信息

javascript - 从 .getJson 多个 .each 循环存储多个对象

javascript - 将类别的文本放在每个栏下方

node.js - require(variable) 导致错误 Cannot find module "."

javascript - 重新加载页面时出现状态未定义错误

javascript - Redux - 商店不起作用

javascript - 使用来自 Firebase 的数据时,卸载组件出现 setState 错误