简体   繁体   中英

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. However, if I try to set the state the props, they don't pick up the subscription values.

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. To have it default to the prop value but be able to update it, pass it as a state.

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 . 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'); }/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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