admin管理员组文章数量:1208155
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;
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.
Share Improve this question edited Mar 8, 2018 at 20:19 Peter Munnings 3,3291 gold badge32 silver badges43 bronze badges asked Nov 21, 2017 at 18:38 Rustam ApayRustam Apay 5911 gold badge4 silver badges18 bronze badges 2- 1 Dispatch is a method controlled by redux, the second parameter of the connect function is a method that maps the actions to the component props and THAT function is passed dispatch. See below for an example code – Joshua Underwood Commented Nov 21, 2017 at 18:50
- 1 Note that I combined your export and connect lines into one statement, renaming the functional component to AddProduct. It appears you added the 0 for brevity's sake rather than trying to come up with another name for it. However, based on the code in the component this isn't necessary. If this helps, please mark the answer as correct. :) PS: Formik can't be added as tag because there is a maximum of five tags. – Joshua Underwood Commented Nov 21, 2017 at 18:56
3 Answers
Reset to default 16I 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);
},
import React from 'react';
import { connect } from 'react-redux';
import { addProduct } from '../actions';
/* AddProduct не совсем контейнер, он просто вызывает диспатч,
ему не нужен стор, поэтому мы можем создать коннект коротким путем:
AddProduct = connect()(AddProduct); */
const AddProduct = ({ addMyProduct }) => {
let inputSKUNumber;
let inputProductName;
return (
<div>
<input
ref={(node) => {
inputSKUNumber = node;
}}
placeholder="SKU Number"
/>
<input
ref={(node) => {
inputProductName = node;
}}
placeholder="Product name"
/>
<button
onClick={() => {
addMyProduct({ SKUNumber: inputSKUNumber.value, name: inputProductName.value });
inputSKUNumber.value = '';
inputProductName.value = '';
}}
>
Add Product
</button>
</div>
);
};
const mapDispatchToProps = dispatch => ({
addMyProduct: (params) => dispatch(addProduct(params))
});
export default connect(null, mapDispatchToProps)(AddProduct);
You can use a higher variable or async function. Higher variable is a little bit lame but working.
let setSubmittingHigher;
// Our inner form component. Will be wrapped with Formik({..})
const MyInnerForm = (props) => {enter code here
.
.
.
handleSubmit(values, {props, setSubmitting}) {
setSubmittingHigher = setSubmitting;
.
.
.
const mapStateToProps = (state) => {
typeof setSubmittingHigher === 'function' && setSubmittingHigher(false);
return {}
};
const mapDispatchToProps = dispatch => ({
addMyProduct: (params) => dispatch(addProduct(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(AddProduct);
本文标签: javascriptHow to connect simple Formik form with Redux store and dispatch an actionStack Overflow
版权声明:本文标题:javascript - How to connect simple Formik form with Redux store and dispatch an action? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738683868a2106711.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论