简体   繁体   English

Meteor React Form不会改变价值

[英]Meteor React Form won't change value

A bit confused on why exactly my inputs won't update. 有点混淆为什么我的输入不会更新。 Essentially, I want to have a profile page. 基本上,我想要一个个人资料页面。 The page is just a form with the fields you can edit. 该页面只是一个包含您可以编辑的字段的表单。 If you already have values for some things (name, etc), I want those to automatically be filled in as the user types with the new values. 如果您已经拥有某些内容的值(名称等),我希望在用户使用新值键入时自动填充这些值。 I imagine it has something to do with trying to overwrite the value with is a "prop" so then I should put the props into "state" for the items. 我想它与尝试用“prop”覆盖值有关,所以我应该把道具放到项目的“状态”中。 However, if I try to set the state the props, they don't pick up the subscription values. 但是,如果我尝试将状态设置为props,则他们不会获取订阅值。

So again, the goal would just be to have the page load, existing values in the person's user document slide into the appropriate fields, edit the fields and submit the changes. 同样,目标只是让页面加载,人员用户文档中的现有值滑入相应的字段,编辑字段并提交更改。 Just the input won't change the value after I try setting it to the props. 在我尝试将其设置为道具后,输入不会更改值。

Any pointers would be appreciated. 任何指针将不胜感激。

Thanks 谢谢

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { getPath } from 'underscore-contrib/underscore.object.selectors';

export default class Profile extends Component {

  constructor(props){
    super(props)
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({value: e.target.value});
  }

  handleSubmit(e) {
    e.preventDefault();
    console.log(e);
    console.log(this.refs)

    // verify the fields
  }

  render() {
    return (
      <div className="profile">
        <h1 className="ui header blue">Profile</h1>

        <form onSubmit={this.handleSubmit.bind(this)} className="profile-form ui form">


          <div className="three fields">
            <div className="field">
              <label>First name</label>
              <input type="text" placeholder="First Name" ref="name.firstName" value={this.props.firstName} onChange={this.handleChange}/>
            </div>
            <div className="field">
              <label>Last name</label>
              <input type="text" placeholder="Last Name" ref="name.lastName" value={this.props.lastName} onChange={this.handleChange}/>
            </div>
            <div className="field">
              <label>Nickname</label>
              <input type="text" placeholder="Nickname" ref="name.nickName" value={this.props.nickName} onChange={this.handleChange}/>
            </div>
          </div>

          <div className="two fields">
            <div className="field">
              <label>Phone</label>
              <input type="text" placeholder="xxx.xxx.xxxx" ref="phoneNumber" value={this.props.phone} onChange={this.handleChange}/>
            </div>
            <div className="field">
              <label>Email</label>
              <input type="email" placeholder="you@email.com" ref="email" value={this.props.email} onChange={this.handleChange}/>
            </div>
          </div>

          <div className="four fields">
            <div className="field">
              <label>DOB</label>
              <input type="text" placeholder="YYYY/DD/MM" ref="body.dob" value={this.props.dob} onChange={this.handleChange}/>
            </div>
            <div className="field">
              <label>City</label>
              <input type="text" placeholder="City" ref="address.city" value={this.props.city} onChange={this.handleChange}/>
            </div>
            <div className="field">
              <label>State</label>
              <input type="text" placeholder="State" ref="address.state" value={this.props.state} onChange={this.handleChange}/>
            </div>

          </div>

          <div className="three fields">
            <div className="field">
              <label>Height</label>
              <div className="ui right labeled input">
                <input type="text" placeholder="Enter height" ref="body.height" value={this.props.height} onChange={this.handleChange}/>
                <div className="ui label">in</div>
              </div>
            </div>
            <div className="field">
              <label>Weight</label>
              <div className="ui right labeled input">
                <input type="text" placeholder="Enter weight" ref="body.weight" value={this.props.weight} onChange={this.handleChange}/>
                <div className="ui label">lbs</div>
              </div>
            </div>
            <div className="field">
              <label>Gender</label>
              <input type="text" placeholder="Male..." ref="body.gender" value={this.props.gender} onChange={this.handleChange}/>
            </div>
          </div>

          <button className="ui button" type="submit">Submit</button>
        </form>

      </div>
    )
  }
}

Profile.propTypes = {
  "firstName": PropTypes.string,
  "lastName" : PropTypes.string,
  "nickName" : PropTypes.string,
  "phone"    : PropTypes.string,
  "email"    : PropTypes.string,
  "dob"      : PropTypes.string,
  "city"     : PropTypes.string,
  "state"    : PropTypes.string,
  "height"   : PropTypes.string,
  "weight"   : PropTypes.string,
  "gender"   : PropTypes.string
}

export default ProfileContainer = createContainer(() => {
  Meteor.subscribe("Meteor.users.publish.name");
  Meteor.subscribe("Meteor.users.publish.phone");
  Meteor.subscribe("Meteor.users.publish.body");
  Meteor.subscribe("Meteor.users.publish.address");

  // build out fields I want in a safe way
  let dict = {
    "firstName": _.getPath(Meteor.user(), 'name.firstName'),
    "lastName" : _.getPath(Meteor.user(), 'name.lastName'),
    "nickName" : _.getPath(Meteor.user(), 'name.nickName'),
    "phone"    : _.getPath(Meteor.user(), 'phone'),
    "email"    : _.getPath(Meteor.user(), 'emails.0.address'),
    "dob"      : _.getPath(Meteor.user(), 'body.dob'),
    "city"     : _.getPath(Meteor.user(), 'address.city'),
    "state"    : _.getPath(Meteor.user(), 'address.state'),
    "height"   : _.getPath(Meteor.user(), 'address.height'),
    "weight"   : _.getPath(Meteor.user(), 'body.weight'),
    "gender"   : _.getPath(Meteor.user(), 'body.gender')
  }

  // create a object to only review the profile items that you want to actually look at
  return {
    "firstName": _.isString(dict.firstName) ? dict.firstName : "",
    "lastName" : _.isString(dict.lastName)  ? dict.lastName  : "",
    "nickName" : _.isString(dict.nickName)  ? dict.nickName  : "",
    "phone"    : _.isString(dict.phone)     ? dict.phone     : "",
    "email"    : _.isString(dict.email)     ? dict.email     : "",
    "dob"      : _.isString(dict.dob)       ? dict.dob       : "",
    "city"     : _.isString(dict.city)      ? dict.city      : "",
    "state"    : _.isString(dict.state)     ? dict.state     : "",
    "height"   : _.isString(dict.height)    ? dict.height    : "",
    "weight"   : _.isString(dict.weight)    ? dict.weight    : "",
    "gender"   : _.isString(dict.gender)    ? dict.gender    : ""
  };
}, Profile);

To be able to update your field value, they must be recorded as a state. 为了能够更新您的字段值,必须将它们记录为状态。 Let's take an example: 我们来举个例子:

<div className="field">
  <label>First name</label>
  <input type="text" placeholder="First Name" ref="name.firstName" value={this.props.firstName} onChange={this.handleChange}/>
</div>

Here, you set your value to this.props.firstName which won't change onChange. 在这里,您将值设置为this.props.firstName ,它不会更改onChange。 To have it default to the prop value but be able to update it, pass it as a state. 要将其默认为prop值但能够更新它,请将其作为状态传递。

constructor(props) {
  super(props);
  this.state = {
    firstName: props.firstName,
  };
}

Then pass the state in your input field. 然后在输入字段中传递状态。 Also, the handleChange function is always updating the same state value . 此外, handleChange函数始终更新相同的状态value You need to tell your function which state to update. 您需要告诉您的功能要更新哪个状态。 You can remove your bind from the constructor and us it as follow: 您可以从构造函数中删除绑定,并按如下方式将其删除:

handleChange(key, e) {
  this.setState({ [key]: e.target.value })
}

and in the render 并在渲染中

<input type="text" placeholder="First Name" ref="name.firstName" value={this.state.firstName} onChange={ () => this.handleChange('firstName'); }/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM