Я создал форму с проверкой с помощью 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, и состояние останется нетронутым (неизменным).
И я не понял, почему вы возвращаете пользователя. Вы назначаете пользователю состояние, а не состояние пользователю.




Я бы посоветовал вам сначала установить значения в состоянии и выполнить проверку. Как только они будут проверены в компоненте, вы можете установить правильные значения в магазине.
`export default class Form extends React.Component{
constructor(props){
super(props);
this.state = {
name:'';
age:''
}
}
handleSubmit=()=>{
if (this.state.name===''){
perform validation
}
else if (this.state.name===''){
}//other validation(s)
else
{
//set data in store only when the fields are correct..
}
}
render(){
return (<div>
<input type = "text" onChange = {(event)=>
{this.setState({name:event.target.value})}} />
<input type = "number" onChange = {(event)=>
{this.setState({age:event.target.value})}} />
<button onClick = {this.handleSubmit}>Submit</button>
</div>)
}
}`
Это поможет вам иметь в магазине только проверенные данные.
Как вы думаете, почему вам следует «снова отправить данные в магазин»? Я думаю, вы можете отправить / опубликовать его на сервере (который в конечном итоге обновит магазин).