javascript - 如何在 React/Redux 应用程序中正确管理表单

标签 javascript forms reactjs redux react-redux

我正在关注一些有关 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 东西。对于应用程序中的每个表单,全局状态都有一个单独的属性。每个 bluronChangesubmit 事件都会调度一个改变状态的操作。 Action 创建者对于所有表单都是通用的,不需要为每个表单单独声明它们,只需将有效负载中的表单 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>
);

}

由于它只有一个属性 Nameform 状态现在应该具有如下结构:

form: {
  AForm: {
     Name: {
       value: '',
       error: ''
     }
  }
} 

此外,应该有一个 Action 创建者:

export function onFormFieldChange(field) {  
  return {
    type: "redux-form/CHANGE"
    field: field.name
    value: field.value,
    form: field.form
  }
}

所有需要的数据都应该作为有效负载传递,这样,reducer 现在就知道要更新什么表单和什么字段。

现在,当连接表单组件时,应将此操作创建者设置为属性:

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 事件处理程序现在应该从 props 中获取:

<input placeholder="Name" name="this.props.name.value"  onChange={this.props.handleChange.bind(this)} />

因此,表单正在以“Redux”方式处理。每次按键时,全局状态都会更新,并且输入将使用新值重新呈现。对于其他事件也应该执行类似的操作,例如 onBLuronFocusonSubmit 等。由于需要做很多工作,因此更加舒适使用Redux Form

这是一个非常粗略的例子。几乎每一行代码都可以增强,希望您能理解其含义。

关于javascript - 如何在 React/Redux 应用程序中正确管理表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38313925/

相关文章:

reactjs - ×对象作为React子对象无效(找到: object with keys {author, quote}). If you meant to render a collection of children, use an array

javascript - 使用javascript为网站body标签中的所有数字添加一个span

javascript - 根容器上的 setState() 不保留 react 导航的路线(V3)

javascript - 无触发器的自定义事件

javascript - 如何为 HTML 数字输入元素设置特定的拒绝消息?

html - Symfony 表单 : how to set default value for a textarea widget

ruby-on-rails - Ruby on Rails 协会表格

reactjs - 在 Docker 中使用 React 和 Nginx 授权 Spotify

javascript - 将图像添加到 JS React Portfolio 时出现错误消息

javascript - 如何为 Ionic 中的每个图像加载添加一个微调器