反应形式道具状态

时间:2018-01-01 16:41:10

标签: reactjs

我有一个Form组件通过其父级传递道具。我希望表单在输入中将这些道具显示为默认值。我想允许对表单进行编辑,然后保存'保存这些新值。

我已经使用了一些我在网上找到的不同解决方案 - 尽管它们似乎都没有允许上述行为。

表单组件 - Form.js

import React, { Component } from 'react';

class ViewBooking extends Component {
  constructor(props) {
    super(props);

    this.state = {
      pitch: this.props.booking.pitch,
      email: this.props.booking.email,
      firstName: this.props.booking.firstName,
      arrivalDate: this.props.booking.arrivalDate,
    }

    this._handleInputChange = this._handleInputChange.bind(this); 
    this._handleUpdateClose = this._handleUpdateClose.bind(this);
    this._handleUpdateBooking = this._handleUpdateBooking.bind(this);
    this._handleDelete = this._handleDelete.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    this.state = {
      pitch: this.nextProps.booking.pitch,
      email: this.nextProps.booking.email,
      firstName: this.nextProps.booking.firstName,
      arrivalDate: this.nextProps.booking.arrivalDate,
    }
  }

  _handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    var partialState = {};
    partialState[name] = value;
    this.setState(partialState);
  }

  _handleUpdateClose(e) {
    this.props.updateClose();
    e.preventDefault();
  }

  _handleUpdateBooking (e) {
    var tempBooking = {
      pitch: this.state.pitch,
      email: this.state.email,
      firstName: this.state.firstName,
      arrivalDate: this.state.arrivalDate,
    }
    this.props.updateBooking(tempBooking);
    e.preventDefault();
  }

  _handleDelete (e) {
    this.props.deleteBooking();
    e.preventDefault();
  }

  render() { 

    if (this.props.viewFormVisibility === true) {
      var viewFormState = {"display": "block"};  
    } else {
      var viewFormState = {"display": "none"};
    }

    return (
      <div>
        <form style={viewFormState}>
          <h4>View Booking</h4>
          <div className="form-group row">
            <label className="col-2 col-form-label">Pitch</label>
            <div className="col-10">
              <input value={this.props.booking.pitch} onChange={this._handleInputChange} className="form-control" name="pitch" ref="inputPitch" type="number" id="example-number-input"/>
            </div>
          </div>
          <div className="form-group row">
            <label  className="col-2 col-form-label">First Name</label>
            <div className="col-10">
              <input value={this.props.booking.firstName} onChange={this._handleInputChange} className="form-control" ref="firstName" name="firstName" type="text" id="example-text-input"/>
            </div>
          </div>
          <div className="form-group row">
            <label className="col-2 col-form-label">Email</label>
            <div className="col-10">
              <input value={this.props.booking.email} onChange={this._handleInputChange} className="form-control" ref="inputEmail" type="email"  name="email" id="example-email-input"/>
            </div>
          </div>

          <div className="form-group row">
            <label className="col-2 col-form-label">Date</label>
            <div className="col-10">
              <input value={this.props.booking.arrivalDate} onChange={this._handleInputChange} className="form-control" ref="arrivalDate" name="arrivalDate" type="date" id="example-date-input"/>
            </div>
          </div>
          <button type="submit" className="btn btn-primary" onClick={this._handleUpdateBooking}>Save changes</button>
          <button className="btn btn-danger" onClick={this._handleUpdateClose}>Close</button>
          <button onClick={this._handleDelete} className="btn btn-danger">Delete</button>
        </form>
      </div>
    )
  }
}

export default ViewBooking;

4 个答案:

答案 0 :(得分:2)

您可以这样做:

class FormParent extends Component {
  constructor (props) {
    super(props)
    this.state = {
      name: ''
    }
    this.handleInputChange = this.handleInputChange.bind(this)
  }
  handleInputChange (e) {
    const { name, value } = e.target
    this.setState({
      [name]: value
    })
  }
  render () {
    const { name } = this.state
    return <Form name={name} handleInputChange={this.handleInputChange} />
  }
}

如果您通过道具传递输入值不需要将它们保存在某个状态,您可以直接将它们设置为输入。

然后要更改输入值,您需要在父级中接收新日期的方法,在本例中为handleInputChange

class Form extends Component {
  render () {
    return (
      <form>
        <input
          name='name'
          value={this.props.name}
          onChange={this.props.handleInputChange}
        />
      </form>
    )
  }
}
  

注意:输入名称应与父状态中的键相同。

答案 1 :(得分:1)

您在componentWillReceiveProps()中所做的不正确。 You should not directly modify the state(除非它是构造函数)。状态更新必须始终通过this.setState()方法进行,如下所示。

componentWillReceiveProps(nextProps) {
    this.setState({
      pitch: nextProps.booking.pitch,
      email: nextProps.booking.email,
      firstName: nextProps.booking.firstName,
      arrivalDate: nextProps.booking.arrivalDate,
    });
 }

除此之外,其余代码似乎都是正确的。

答案 2 :(得分:0)

您的代码中存在许多错误。我修好了它们,下面是工作代码。

class ViewBooking extends Component {
  constructor(props) {
    super(props)

    this.state = {
      pitch: props.booking.pitch,
      email: props.booking.email,
      firstName: props.booking.firstName,
      arrivalDate: props.booking.arrivalDate
    }

    this._handleInputChange = this._handleInputChange.bind(this)
    this._handleUpdateClose = this._handleUpdateClose.bind(this)
    this._handleUpdateBooking = this._handleUpdateBooking.bind(this)
    this._handleDelete = this._handleDelete.bind(this)
  }

  componentWillReceiveProps(nextProps) {
    this.state = {
      pitch: nextProps.booking.pitch,
      email: nextProps.booking.email,
      firstName: nextProps.booking.firstName,
      arrivalDate: nextProps.booking.arrivalDate
    }
  }

  _handleInputChange(event) {
    const target = event.target
    const value = target.type === 'checkbox' ? target.checked : target.value
    const name = target.name
    var partialState = {}
    partialState[name] = value
    this.setState(partialState)
  }

  _handleUpdateClose(e) {
    this.props.updateClose()
    e.preventDefault()
  }

  _handleUpdateBooking(e) {
    var tempBooking = {
      pitch: this.state.pitch,
      email: this.state.email,
      firstName: this.state.firstName,
      arrivalDate: this.state.arrivalDate
    }
    this.props.updateBooking(tempBooking)
    e.preventDefault()
  }

  _handleDelete(e) {
    this.props.deleteBooking()
    e.preventDefault()
  }

  render() {
    if (this.props.viewFormVisibility === true) {
      var viewFormState = { 'display': 'block' }
    } else {
      var viewFormState = { 'display': 'none' }
    }

    return (
      <div>
        fdsfdsfdf
        <form style={viewFormState}>
          <h4>View Booking</h4>
          <div className='form-group row'>
            <label className='col-2 col-form-label'>Pitch</label>
            <div className='col-10'>
              <input value={this.state.pitch} onChange={this._handleInputChange} className='form-control' name='pitch' ref='inputPitch' type='number' id='example-number-input' />
            </div>
          </div>
          <div className='form-group row'>
            <label className='col-2 col-form-label'>First Name</label>
            <div className='col-10'>
              <input value={this.state.firstName} onChange={this._handleInputChange} className='form-control' ref='firstName' name='firstName' type='text' id='example-text-input' />
            </div>
          </div>
          <div className='form-group row'>
            <label className='col-2 col-form-label'>Email</label>
            <div className='col-10'>
              <input value={this.state.email} onChange={this._handleInputChange} className='form-control' ref='inputEmail' type='email' name='email' id='example-email-input' />
            </div>
          </div>

          <div className='form-group row'>
            <label className='col-2 col-form-label'>Date</label>
            <div className='col-10'>
              <input value={this.state.arrivalDate} onChange={this._handleInputChange} className='form-control' ref='arrivalDate' name='arrivalDate' type='date' id='example-date-input' />
            </div>
          </div>
          <button type='submit' className='btn btn-primary' onClick={this._handleUpdateBooking}>Save changes</button>
          <button className='btn btn-danger' onClick={this._handleUpdateClose}>Close</button>
          <button onClick={this._handleDelete} className='btn btn-danger'>Delete</button>
        </form>
      </div>
    )
  }
}

答案 3 :(得分:0)

这是一个使用父级道具输入文字的演示。

https://codepen.io/seanwasere/pen/KBWNaL?editors=0010

class Form extends React.Component {
  constructor () {
    super()
    this.state = {
      data: ''
    }
    this.handleChange = this.handleChange.bind(this)
  }
  handleChange (e) {
    const newData = e.target.value
    this.setState({
      data: newData
    })
  }
  render () {
    const { data } = this.state
    return (
      <div>
        <form>
          <label>
            Type something:
            <TextInput value={data} handleInputChange={this.handleChange} />
          </label>
          <div>
            You typed : {data}
          </div>
        </form>
        </div>
      )
   }
}

class TextInput extends React.Component {
  render () {
    return (      
        <input
          value={this.props.data}
          onChange={this.props.handleInputChange}
        />      
    )
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('root')
);