如何在 React/Redux 应用程序中正确管理表单
How to properly manage forms in React/Redux app
我正在学习一些关于 React/Redux 的教程。
我不清楚的部分是输入表格。
我的意思是如何处理变化以及在哪里管理状态
这是一个非常简单的表单,只有一个字段。
export default class UserAdd extends React.Component {
static propTypes = {
onUserSubmit: React.PropTypes.func.isRequired
}
constructor (props, context) {
super(props, context);
this.state = {
name: this.props.name
};
}
render () {
return (
<form
onSubmit={e => {
e.preventDefault()
this.handleSubmit()
}}
>
<input
placeholder="Name"
onChange={this.handleChange.bind(this)}
/>
<input type="submit" value="Add" />
</form>
);
}
handleChange (e) {
this.setState({ name: e.target.value });
}
handleSubmit () {
this.props.onUserSubmit(this.state.name);
this.setState({ name: '' });
}
}
我觉得这就像打破了 Redux 哲学,因为表示组件正在更新状态,对吗?
这是要与表示组件耦合的连接组件。
const mapDispatchToProps = (dispatch) => {
return {
onUserSubmit: (name) => {
dispatch(addUser(name))
}
}
}
const UserAddContainer = connect(
undefined,
mapDispatchToProps
)(UserAdd)
这是正确的遵循方式,还是我把事情搞混了?
在 UserAdd 组件中调用 setState 并在按下每个键时更新状态 (handleChange) 是否正确?
谢谢
有一个不错的库 Redux Form 用于通过以 Redux 方式更新全局存储来处理表单。有了它的帮助,您不必为每个输入设置操作,只需为整个表单及其状态设置操作即可。看看吧。
这个库的主要原则在于通过调度 redux 操作来更新输入值,而不是使用 setState
东西。对于应用程序中的每个表单,全局状态中都有一个单独的 property
。每个 blur
、onChange
、submit
事件都会调度一个改变状态的动作。 Action creators 对所有表单都是通用的,不需要为每个表单单独声明它们,只需将有效负载中的表单 id 或名称传递给 reducer,这样它就可以知道应该更新哪个表单的 属性 。
例如。在应用程序状态中应该设置一个 属性 form
作为普通对象。应用程序中的每个新表单都应该在其中存储它的状态。让我们给你的表单一个名称属性,所以它应该作为我们的标识符。
render () {
return (
<form
name="AForm"
onSubmit={e => {
e.preventDefault()
this.handleSubmit()
}}
>
<input
name="name"
placeholder="Name"
onChange={this.handleChange.bind(this)}
/>
<input type="submit" value="Add" />
</form>
);
}
因为它只有一个 属性 Name
,form 状态现在应该有这样的结构:
form: {
AForm: {
Name: {
value: '',
error: ''
}
}
}
此外,应该有一个动作创建者:
export function onFormFieldChange(field) {
return {
type: "redux-form/CHANGE"
field: field.name
value: field.value,
form: field.form
}
}
所有需要的数据都应该作为有效负载传递,这样 reducer 现在就会知道要更新什么表单和什么字段。
现在,当连接表单组件时,这个action creator应该设置为属性:
import { onFormFieldChange } from `path-to-file-wit-actions`
const mapStateToProps = (state, ownProps) => {
const { AForm } = state.form
return {
name: AForm.name
}
}
const mapDispatchToProps = (dispatch) => {
return {
onChange: (e) => {
dispatch(onFormFieldChange({
field: 'name',
value: e.target.value,
form: 'AForm'
}))
},
onUserSubmit: (name) => {
dispatch(addUser(name))
}
}
}
const UserAddContainer = connect(
undefined,
mapDispatchToProps
)(UserAdd)
在组件中,字段值和 onChange
事件处理程序现在应该取自道具:
<input placeholder="Name" name="this.props.name.value" onChange={this.props.handleChange.bind(this)} />
因此,表单以 "Redux" 的方式处理。在每次按键时,全局状态将被更新,输入将使用它的新值重新呈现。其他事件也应该做类似的事情,比如 onBLur
、onFocus
、onSubmit
等。由于要做很多工作,所以使用 Redux Form 会更舒服。
这是一个非常粗略的例子。几乎每一行代码都可以得到增强,希望您能理解其含义。
我通常使用 this.setState()
将我的表单状态存储在表单组件中,并且只使用完整的表单对象触发一个动作,该对象被传递给某种 POST
ajax 调用.
我正在学习一些关于 React/Redux 的教程。 我不清楚的部分是输入表格。 我的意思是如何处理变化以及在哪里管理状态 这是一个非常简单的表单,只有一个字段。
export default class UserAdd extends React.Component {
static propTypes = {
onUserSubmit: React.PropTypes.func.isRequired
}
constructor (props, context) {
super(props, context);
this.state = {
name: this.props.name
};
}
render () {
return (
<form
onSubmit={e => {
e.preventDefault()
this.handleSubmit()
}}
>
<input
placeholder="Name"
onChange={this.handleChange.bind(this)}
/>
<input type="submit" value="Add" />
</form>
);
}
handleChange (e) {
this.setState({ name: e.target.value });
}
handleSubmit () {
this.props.onUserSubmit(this.state.name);
this.setState({ name: '' });
}
}
我觉得这就像打破了 Redux 哲学,因为表示组件正在更新状态,对吗? 这是要与表示组件耦合的连接组件。
const mapDispatchToProps = (dispatch) => {
return {
onUserSubmit: (name) => {
dispatch(addUser(name))
}
}
}
const UserAddContainer = connect(
undefined,
mapDispatchToProps
)(UserAdd)
这是正确的遵循方式,还是我把事情搞混了? 在 UserAdd 组件中调用 setState 并在按下每个键时更新状态 (handleChange) 是否正确?
谢谢
有一个不错的库 Redux Form 用于通过以 Redux 方式更新全局存储来处理表单。有了它的帮助,您不必为每个输入设置操作,只需为整个表单及其状态设置操作即可。看看吧。
这个库的主要原则在于通过调度 redux 操作来更新输入值,而不是使用 setState
东西。对于应用程序中的每个表单,全局状态中都有一个单独的 property
。每个 blur
、onChange
、submit
事件都会调度一个改变状态的动作。 Action creators 对所有表单都是通用的,不需要为每个表单单独声明它们,只需将有效负载中的表单 id 或名称传递给 reducer,这样它就可以知道应该更新哪个表单的 属性 。
例如。在应用程序状态中应该设置一个 属性 form
作为普通对象。应用程序中的每个新表单都应该在其中存储它的状态。让我们给你的表单一个名称属性,所以它应该作为我们的标识符。
render () {
return (
<form
name="AForm"
onSubmit={e => {
e.preventDefault()
this.handleSubmit()
}}
>
<input
name="name"
placeholder="Name"
onChange={this.handleChange.bind(this)}
/>
<input type="submit" value="Add" />
</form>
);
}
因为它只有一个 属性 Name
,form 状态现在应该有这样的结构:
form: {
AForm: {
Name: {
value: '',
error: ''
}
}
}
此外,应该有一个动作创建者:
export function onFormFieldChange(field) {
return {
type: "redux-form/CHANGE"
field: field.name
value: field.value,
form: field.form
}
}
所有需要的数据都应该作为有效负载传递,这样 reducer 现在就会知道要更新什么表单和什么字段。
现在,当连接表单组件时,这个action creator应该设置为属性:
import { onFormFieldChange } from `path-to-file-wit-actions`
const mapStateToProps = (state, ownProps) => {
const { AForm } = state.form
return {
name: AForm.name
}
}
const mapDispatchToProps = (dispatch) => {
return {
onChange: (e) => {
dispatch(onFormFieldChange({
field: 'name',
value: e.target.value,
form: 'AForm'
}))
},
onUserSubmit: (name) => {
dispatch(addUser(name))
}
}
}
const UserAddContainer = connect(
undefined,
mapDispatchToProps
)(UserAdd)
在组件中,字段值和 onChange
事件处理程序现在应该取自道具:
<input placeholder="Name" name="this.props.name.value" onChange={this.props.handleChange.bind(this)} />
因此,表单以 "Redux" 的方式处理。在每次按键时,全局状态将被更新,输入将使用它的新值重新呈现。其他事件也应该做类似的事情,比如 onBLur
、onFocus
、onSubmit
等。由于要做很多工作,所以使用 Redux Form 会更舒服。
这是一个非常粗略的例子。几乎每一行代码都可以得到增强,希望您能理解其含义。
我通常使用 this.setState()
将我的表单状态存储在表单组件中,并且只使用完整的表单对象触发一个动作,该对象被传递给某种 POST
ajax 调用.