React/Redux 通过点击预填充表单
React/Redux pre populating a form on a click
我试图在单击我的 Item
中的按钮后预填充我的表单我有能够更新项目的操作,问题是能够使用正确的项目能够发送该操作。
-----------------
| + List | << Name of the list
-----------------
| SKU: 12345 | << Item
| ITEM: Bananas |
| PRICE: .00 |
| |
| <edit> | << Button triggering the modal and form. Need to pre-populate the form onClick
-----------------
/components/List.jsx
export class List extends React.Component {
constructor(props) {
super(props)
this.state = {
isModalOpen: false
}
}
toggleModal () {
this.setState({ isModalOpen: !this.state.isModalOpen })
}
...
render () {
const { list, ...props } = this.props
const listId = list.id
return (
...
<Items
items={props.listItems}
openModal={this.toggleModal.bind(this)}>
</Items>
<Modal
className='list-add-item'
openModal={this.state.isModalOpen}>
<ItemForm
itemActions={this.props.itemActions}
listActions={this.props.listActions}
listId={listId}>
</ItemForm>
</Modal>
</div>
)
}
}
/components/ItemForm.jsx
import React from 'react'
import uuid from 'node-uuid'
class ItemForm extends React.Component {
constructor(props) {
super(props)
this.state = {
isEditing: false
}
}
handleSubmit = (event) => {
event.preventDefault()
let sku = this.refs.sku.value.trim()
let text = this.refs.text.value.trim()
let price = this.refs.price.value.trim()
const item = { id: uuid.v4(), sku, text, price }
// don't do anything if any field is left blank
if (!item.sku || !item.text || !item.price) { return }
this.props.itemActions.createItem(item)
this.props.listActions.connectToList(this.props.listId, item.id)
// reset the form after submission
this.refs.itemForm.reset()
}
render() {
const { ...props } = this.props
return (
<form ref="itemForm" onSubmit={this.handleSubmit}>
<label>SKU</label>
<input
type="text"
placeholder="SKU"
autoFocus={true}
ref='sku'
defaultValue={this.props.sku}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<label>Item</label>
<input
type="text"
placeholder="Item"
autoFocus={true}
ref='text'
defaultValue={this.props.text}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<label>Price</label>
<input
type="text"
placeholder="Price"
autoFocus={true}
ref='price'
defaultValue={this.props.price}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<button type="submit">{ this.state.isEditing ? 'Edit Item' : 'Add Item' }</button>
</form>
)
}
}
export default ItemForm
/components/Items.jsx
export default class Items extends React.Component {
render () {
const {items, onEdit, ...props} = this.props
return (
<ul className='items'>{items.map((item) =>
<Item
className='item'
key={item.id}
id={item.id}
sku={item.sku}
text={item.text}
price={item.price}
openModal={this.props.openModal}>
</Item>
)}</ul>
)
}
}
/components/Item.jsx
export default class Item extends React.Component {
render () {
const { openModal, ...props } = this.props
return (
<span>
<li>SKU: {this.props.sku}</li>
<li>ITEM: {this.props.text}</li>
<li>PRICE: {this.props.price}</li>
<button onClick={this.props.openModal}>Edit Item</button>
</span>
)
}
}
有多种方法可以做到这一点。例如,您可以按照以下步骤操作:
- components/list:添加一个内部状态来知道每时每刻从列表中选择了哪个项目。将此
selectedItem
作为道具传递给 itemForm
。创建一个方法 selectItem
来更新该状态。将此 selectItem
方法作为道具传递给您的 components/items。记得bind
它到组件。
- components/items:添加为
onClick
处理程序,selectItem
作为 props 传递给组件。
- components/itemForm:在
constructor
中使用道具中传递的项目信息创建状态。添加 willReceiveProps
并在每次收到可能包含新选定项目的更新道具时更新组件的内部状态。
希望这对您有所帮助并解决了您的问题。
我最终改用了 redux-form,我的应用程序的设置方式让我很难解决我遇到的问题。工作版本是 here
我试图在单击我的 Item
中的按钮后预填充我的表单我有能够更新项目的操作,问题是能够使用正确的项目能够发送该操作。
-----------------
| + List | << Name of the list
-----------------
| SKU: 12345 | << Item
| ITEM: Bananas |
| PRICE: .00 |
| |
| <edit> | << Button triggering the modal and form. Need to pre-populate the form onClick
-----------------
/components/List.jsx
export class List extends React.Component {
constructor(props) {
super(props)
this.state = {
isModalOpen: false
}
}
toggleModal () {
this.setState({ isModalOpen: !this.state.isModalOpen })
}
...
render () {
const { list, ...props } = this.props
const listId = list.id
return (
...
<Items
items={props.listItems}
openModal={this.toggleModal.bind(this)}>
</Items>
<Modal
className='list-add-item'
openModal={this.state.isModalOpen}>
<ItemForm
itemActions={this.props.itemActions}
listActions={this.props.listActions}
listId={listId}>
</ItemForm>
</Modal>
</div>
)
}
}
/components/ItemForm.jsx
import React from 'react'
import uuid from 'node-uuid'
class ItemForm extends React.Component {
constructor(props) {
super(props)
this.state = {
isEditing: false
}
}
handleSubmit = (event) => {
event.preventDefault()
let sku = this.refs.sku.value.trim()
let text = this.refs.text.value.trim()
let price = this.refs.price.value.trim()
const item = { id: uuid.v4(), sku, text, price }
// don't do anything if any field is left blank
if (!item.sku || !item.text || !item.price) { return }
this.props.itemActions.createItem(item)
this.props.listActions.connectToList(this.props.listId, item.id)
// reset the form after submission
this.refs.itemForm.reset()
}
render() {
const { ...props } = this.props
return (
<form ref="itemForm" onSubmit={this.handleSubmit}>
<label>SKU</label>
<input
type="text"
placeholder="SKU"
autoFocus={true}
ref='sku'
defaultValue={this.props.sku}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<label>Item</label>
<input
type="text"
placeholder="Item"
autoFocus={true}
ref='text'
defaultValue={this.props.text}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<label>Price</label>
<input
type="text"
placeholder="Price"
autoFocus={true}
ref='price'
defaultValue={this.props.price}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}></input>
<button type="submit">{ this.state.isEditing ? 'Edit Item' : 'Add Item' }</button>
</form>
)
}
}
export default ItemForm
/components/Items.jsx
export default class Items extends React.Component {
render () {
const {items, onEdit, ...props} = this.props
return (
<ul className='items'>{items.map((item) =>
<Item
className='item'
key={item.id}
id={item.id}
sku={item.sku}
text={item.text}
price={item.price}
openModal={this.props.openModal}>
</Item>
)}</ul>
)
}
}
/components/Item.jsx
export default class Item extends React.Component {
render () {
const { openModal, ...props } = this.props
return (
<span>
<li>SKU: {this.props.sku}</li>
<li>ITEM: {this.props.text}</li>
<li>PRICE: {this.props.price}</li>
<button onClick={this.props.openModal}>Edit Item</button>
</span>
)
}
}
有多种方法可以做到这一点。例如,您可以按照以下步骤操作:
- components/list:添加一个内部状态来知道每时每刻从列表中选择了哪个项目。将此
selectedItem
作为道具传递给itemForm
。创建一个方法selectItem
来更新该状态。将此selectItem
方法作为道具传递给您的 components/items。记得bind
它到组件。 - components/items:添加为
onClick
处理程序,selectItem
作为 props 传递给组件。 - components/itemForm:在
constructor
中使用道具中传递的项目信息创建状态。添加willReceiveProps
并在每次收到可能包含新选定项目的更新道具时更新组件的内部状态。
希望这对您有所帮助并解决了您的问题。
我最终改用了 redux-form,我的应用程序的设置方式让我很难解决我遇到的问题。工作版本是 here