我有一个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;
答案 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')
);