如何将简单的 Formik 表单与 Redux 存储连接并分派动作? [英] How to connect simple Formik form with Redux store and dispatch an action?
问题描述
我是 react/redux 的新手,但可以为我的应用实现一些简单的 addProduct 表单.今天我尝试用 Formik 从这个 基本演示,但我不明白我应该在哪里放置调度"功能(我到处都试过了).
可能是我以错误的方式使用了连接?
我的新组件与 Demo 中的完全一样,除了我用 productName(和其他附加字段)替换了电子邮件).但我无法理解如何将值"从 Formik 传递到 Redux 存储.
我的旧表单组件,没有 Formik,看起来像这样:
从'react'导入React;从'react-redux'导入{连接};从'../actions' 导入 { addProduct };const AddProduct0 = ({ dispatch }) =>{让输入SKU编号;让输入产品名称;返回 (<div><输入ref={(节点)=>{inputSKUNumber = 节点;}}占位符="SKU 编号"/><输入ref={(节点)=>{输入产品名称 = 节点;}}占位符=产品名称"/><按钮onClick={() =>{dispatch(addProduct({ SKUNumber: inputSKUNumber.value, name: inputProductName.value }));inputSKUNumber.value = '';inputProductName.value = '';}}>添加产品按钮>
);};const AddProduct = connect()(AddProduct0);导出默认添加产品;
我使用 formik 的新组件如下所示:
从'react'导入React;从'react-redux'导入{连接};从'formik'导入{ withFormik };从 'yup' 导入 Yup;从'../actions' 导入 { addProduct };导入'./helper.css';//我们的内部表单组件.将被 Formik({..}) 包裹const MyInnerForm = (props) =>{常量{价值观,感动,错误,肮脏的,正在提交,处理更改,处理模糊,处理提交,手柄重置,} = 道具;返回 (<form onSubmit={handleSubmit}><label htmlFor="SKUNumber">SKU 编号</label><输入id="SKU 编号"占位符="SKU 编号"类型=数字"值={values.SKUNumber}onChange={handleChange}onBlur={handleBlur}className={errors.SKUNumber &&触摸.SKU编号?文本输入错误":文本输入"}/><div className="input-feedback">{touched.SKUNumber ?errors.SKUNumber : ''}</div><label htmlFor="productName">产品名称</label><输入id="产品名称"占位符=产品名称"类型=文本"值={values.productName}onChange={handleChange}onBlur={handleBlur}className={errors.productName &&触摸.产品名称?文本输入错误":文本输入"}/><div className="input-feedback">{touched.productName ?errors.productName : ''}</div><按钮类型=按钮"类名=大纲"onClick={handleReset}禁用={!脏||正在提交}>重启按钮><button type="submit" disabled={isSubmitting}>提交按钮><DisplayFormikState {...props}/></表单>);};const EnhancedForm = withFormik({mapPropsToValues: () =>({SKU 编号:12345678,productName: '默认产品',}),验证架构:是的.对象().形状({SKU 编号:是的.编号().max(99999999, 'SKU 编号必须小于 8 位').required('SKU 编号为必填项!'),产品名称:Yup.string().min(5, '产品名称必须长于 5 个符号').max(50, '产品名称必须少于 50 个符号').required('产品名称为必填项!'),handleSubmit: (values, { setSubmitting }) =>{setTimeout(() => {警报(JSON.stringify(值,空,2));设置提交(假);}, 1000);//dispatch(addProduct(values));},displayName: 'BasicForm',//帮助 React DevTools})(MyInnerForm);export const DisplayFormikState = props =>(<div style={{ margin: '1rem 0' }}><h3 style={{ fontFamily: 'monospace' }}/><预风格={{背景:'#f6f8fa',字体大小:'.65rem',填充:'.5rem',}}><strong>道具</strong>= {JSON.stringify(props, null, 2)}
);const AddProduct = connect()(EnhancedForm);导出默认添加产品;
附言如果有人在这里有声望添加标签formik",请这样做.
我还在 formik 页面上打开了一个问题.其中一位贡献者给了我答案.一切都适用于该代码:
handleSubmit(values, { props, setSubmitting }) {props.dispatch(addProduct(values));设置提交(假);},
I'm new at react/redux, but can realize some simple addProduct form for my app. Today I tried to replace it with Formik from this Basic demo, but I cant't understand where should I place "dispatch" function (I tried it to everywhere).
May be I use connect in wrong way?
My new component is exactly like in Demo, except I replaced email with productName (and other additional fields). But I can't understand how to pass "values" from Formik to Redux store.
My old form component, without Formik, looks like this:
import React from 'react';
import { connect } from 'react-redux';
import { addProduct } from '../actions';
const AddProduct0 = ({ dispatch }) => {
let inputSKUNumber;
let inputProductName;
return (
<div>
<input
ref={(node) => {
inputSKUNumber = node;
}}
placeholder="SKU Number"
/>
<input
ref={(node) => {
inputProductName = node;
}}
placeholder="Product name"
/>
<button
onClick={() => {
dispatch(addProduct({ SKUNumber: inputSKUNumber.value, name: inputProductName.value }));
inputSKUNumber.value = '';
inputProductName.value = '';
}}
>
Add Product
</button>
</div>
);
};
const AddProduct = connect()(AddProduct0);
export default AddProduct;
My new component with formik looks like this:
import React from 'react';
import { connect } from 'react-redux';
import { withFormik } from 'formik';
import Yup from 'yup';
import { addProduct } from '../actions';
import './helper.css';
// Our inner form component. Will be wrapped with Formik({..})
const MyInnerForm = (props) => {
const {
values,
touched,
errors,
dirty,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
handleReset,
} = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="SKUNumber">SKU Number</label>
<input
id="SKUNumber"
placeholder="SKU Number"
type="number"
value={values.SKUNumber}
onChange={handleChange}
onBlur={handleBlur}
className={errors.SKUNumber && touched.SKUNumber ? 'text-input error' : 'text-input'}
/>
<div className="input-feedback">{touched.SKUNumber ? errors.SKUNumber : ''}</div>
<label htmlFor="productName">Product Name</label>
<input
id="productName"
placeholder="Product Name"
type="text"
value={values.productName}
onChange={handleChange}
onBlur={handleBlur}
className={errors.productName && touched.productName ? 'text-input error' : 'text-input'}
/>
<div className="input-feedback">{touched.productName ? errors.productName : ''}</div>
<button
type="button"
className="outline"
onClick={handleReset}
disabled={!dirty || isSubmitting}
>
Reset
</button>
<button type="submit" disabled={isSubmitting}>
Submit
</button>
<DisplayFormikState {...props} />
</form>
);
};
const EnhancedForm = withFormik({
mapPropsToValues: () => ({
SKUNumber: 12345678,
productName: 'Default Product',
}),
validationSchema: Yup.object().shape({
SKUNumber: Yup.number()
.max(99999999, 'SKU Number must be less than 8 digits')
.required('SKU Number is required!'),
productName: Yup.string()
.min(5, 'Product name must be longer than 5 symbols')
.max(50, 'Product name must be shorter than 50 symbols')
.required('Product name is required!'),
handleSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 1000);
// dispatch(addProduct(values));
},
displayName: 'BasicForm', // helps with React DevTools
})(MyInnerForm);
export const DisplayFormikState = props => (
<div style={{ margin: '1rem 0' }}>
<h3 style={{ fontFamily: 'monospace' }} />
<pre
style={{
background: '#f6f8fa',
fontSize: '.65rem',
padding: '.5rem',
}}
>
<strong>props</strong> = {JSON.stringify(props, null, 2)}
</pre>
</div>
);
const AddProduct = connect()(EnhancedForm);
export default AddProduct;
p.s. If someone have reputation here to add tag "formik", please, do it.
I also opened an issue on formik page. And there one of contributors gave me the answer. All works with that code:
handleSubmit(values, { props, setSubmitting }) {
props.dispatch(addProduct(values));
setSubmitting(false);
},
这篇关于如何将简单的 Formik 表单与 Redux 存储连接并分派动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!