【发布时间】:2018-11-08 01:21:30
【问题描述】:
我使用 React 和 Redux 创建了带有验证的表单。 验证条件:
- 数据应在输入时进行验证
- 提交前需再次验证数据
- 所有数据所有字段均为必填且数据有效
当用户开始输入数据时,我检查数据并在输入时使用调度将它们发送到商店。 当用户首先单击“提交”按钮时,我会检查数据是否有价值并将其状态发送到商店。
问题:
如果提交时所有数据都具有有效值,是否需要我再次将数据发送到商店?
我的操作./actions/index.js:
export const changeValue = (field, value, isValid) => ({
type: "CHANGE_VALUE",
value, isValid, field
})
我的减速器 ./reducers/form.js :
const form = (state={
firstName: {isValid: true, value: ''},
mail: { isValid: true, value: ''}
}, action) => {
switch (action.type) {
case 'CHANGE_VALUE':
state[action.field].isValid = action.isValid
state[action.field].value = action.value
const user = Object.assign({}, state)
return user
default:
return state
}
}
export default form
我的表单容器 ./containers/Form.js ::
import React from 'react'
import { connect } from 'react-redux'
import { changeValue } from '../actions'
const hasOnlyLetters = value => value.match(/^[a-zA-Z]+$/)
const re = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i
const hasEmail = value => value.match(re)
const Form = ({ dispatch, inputs }) => {
// Check the data at the time of the data input
const changeHandler = (isValid, field, e) => {
const { value } = e.target
if (isValid(value)){
dispatch(changeValue(field, value, true))
} else {
dispatch(changeValue(field, value, false))
}
}
// Check the data before submission
const handleSubmit = (e) => {
e.preventDefault()
if (!inputs.firstName.value) {
dispatch(changeValue('firstName', inputs.firstName.value, false))
}
if (!inputs.mail.value) {
dispatch(changeValue('mail', inputs.lastName.value, false))
}
if(!inputs.firstName.isValid || !inputs.mail.isValid) {
return alert('error')
} else {
// Send the data to the store again?
return alert('success')
}
}
const error = (field, type) => {
if (!field.value && !field.isValid) {
return <span>Field is required</span>
} else if (field.value && !field.isValid && type === "text") {
return <span>Should contain only letters</span>
} else if (field.value && !field.isValid && type === "mail") {
return <span>Value should be a valid email</span>
} else{
null
}
}
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<label>First name:</label>
<input type="text" value={inputs.firstName.value} onChange={changeHandler.bind(null, hasOnlyLetters, 'firstName')}/>
{ error(inputs.firstName, "text") }
</div>
<div>
<label>Email:</label>
<input type="mail" value={inputs.mail.value} onChange={changeHandler.bind(null, hasEmail, 'mail')}/>
{ error(inputs.mail, "mail") }
</div>
<button type="submit">
Add Todo
</button>
</form>
</div>
)
}
function mapStateToProps(state) {
return { inputs: state.form }
}
export default connect(mapStateToProps)(Form)
【问题讨论】:
-
为什么您认为应该“再次将数据发送到存储区”?我猜您可能会将其发送/发布到后端(最终会更新商店)。
-
我不知道你在问什么。您可以根据需要多次发送数据,然后将其合并。如果您想防止重复提交,只需在单击并验证数据后禁用提交按钮。
-
提示:我建议在调度程序中编写状态更新,如下所示:
return {...state, [action.field]: {value: action.value, isValid: action.isValid}}。这样你就不需要user并且状态保持不变(不可变)。 -
我不明白你为什么返回用户。您将用户分配给状态而不是状态分配给用户。
标签: forms reactjs validation redux jsx