最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using setFieldValue for one field, based on another filed values - Stack Overflow

programmeradmin2浏览0评论

I'm using formik react library and trying to update 2 fields, based on the onChange event of another. For example,

price = quantity * totalPrice

price :
onChange={() => {setFieldValue('quantity',values.quantity? values.price / values.totalPrice:values.quantity, );
setFieldValue('totalPrice',values.totalPrice? values.price * values.quantity: values.totalPrice,);}}

quantity :
onChange={(value, e) => { this.disableFiled(value, e); setFieldValue('totalPrice',values.price ? values.price * values.totalPrice : ' ',);}}

totalPrice:
onChange={(value, e) => { this.disableFiled(value, e);setFieldValue('quantity',values.price ? values.totalPrice / price : ' ', ); }}

when quantity has value, total price will be disabled and vice versa.but it doesn't calculate other fields correctly

I'm using formik react library and trying to update 2 fields, based on the onChange event of another. For example,

price = quantity * totalPrice

price :
onChange={() => {setFieldValue('quantity',values.quantity? values.price / values.totalPrice:values.quantity, );
setFieldValue('totalPrice',values.totalPrice? values.price * values.quantity: values.totalPrice,);}}

quantity :
onChange={(value, e) => { this.disableFiled(value, e); setFieldValue('totalPrice',values.price ? values.price * values.totalPrice : ' ',);}}

totalPrice:
onChange={(value, e) => { this.disableFiled(value, e);setFieldValue('quantity',values.price ? values.totalPrice / price : ' ', ); }}

when quantity has value, total price will be disabled and vice versa.but it doesn't calculate other fields correctly

Share Improve this question edited Sep 24, 2019 at 10:34 Rahele Nazari asked Sep 24, 2019 at 8:32 Rahele NazariRahele Nazari 4012 gold badges5 silver badges13 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 12

This is how I do this.

App.js file:

import React from "react";
import "./styles.css";
import { Formik } from "formik";
import * as Yup from "yup";
import CalculatedField from "./CalculatedField";

const App = () => (
  <div className="app">
    <Formik
      initialValues={{ price: "", quantity: "", totalPrice: "" }}
      onSubmit={async values => {
        await new Promise(resolve => setTimeout(resolve, 500));
        alert(JSON.stringify(values, null, 2));
      }}
      validationSchema={Yup.object().shape({
        price: Yup.number("It's a number").required("Required"),
        quantity: Yup.number("It's a number").required("Required"),
        totalPrice: Yup.number("It's a number").required("Required")
      })}
    >
      {props => {
        const {
          values,
          touched,
          errors,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit,
          setFieldValue
        } = props;
        return (
          <form onSubmit={handleSubmit}>
            <div className="input-row">
              <label htmlFor="quantity" style={{ display: "block" }}>
                Quantity
              </label>
              <input
                id="quantity"
                name="quantity"
                placeholder="Enter quantity"
                type="number"
                value={values.quantity}
                onChange={handleChange}
                onBlur={handleBlur}
                className={
                  errors.quantity && touched.quantity
                    ? "text-input error"
                    : "text-input"
                }
              />
              {errors.quantity && touched.quantity && (
                <div className="input-feedback">{errors.quantity}</div>
              )}
            </div>
            <div className="input-row">
              <label htmlFor="price" style={{ display: "block" }}>
                Price
              </label>
              <input
                id="price"
                name="price"
                placeholder="Enter your price"
                type="number"
                value={values.price}
                onChange={handleChange}
                onBlur={handleBlur}
                className={
                  errors.price && touched.price
                    ? "text-input error"
                    : "text-input"
                }
              />
              {errors.price && touched.price && (
                <div className="input-feedback">{errors.price}</div>
              )}
            </div>

            <div className="input-row">
              <label htmlFor="totalPrice" style={{ display: "block" }}>
                Total Price
              </label>
              <CalculatedField
                id="totalPrice"
                type="number"
                name="totalPrice"
                value={values.totalPrice}
                values={values}
                setFieldValue={setFieldValue}
                onChange={handleChange}
                onBlur={handleBlur}
                className={
                  errors.totalPrice && touched.totalPrice
                    ? "text-input error"
                    : "text-input"
                }
              />
              {errors.totalPrice && touched.totalPrice && (
                <div className="input-feedback">{errors.totalPrice}</div>
              )}
            </div>

            <div className="input-row">
              <button type="submit" disabled={isSubmitting}>
                Submit
              </button>
            </div>
          </form>
        );
      }}
    </Formik>
  </div>
);
export default App;

CalculatedField.js

import React, { useEffect } from "react";

const CalculatedField = props => {
  useEffect(() => {
    var val = 0;
    if (props.values.price && props.values.quantity) {
      val = props.values.price * props.values.quantity;
    }
    props.setFieldValue("totalPrice", val);
  }, [props.values]);

  return (
    <input
      id="totalPrice"
      type="number"
      name="totalPrice"
      value={props.values.totalPrice}
    />
  );
};

export default CalculatedField;

This is basically achieved by calling setFieldValue method within useEffect hooks in the CalculatedField component. Please remember useEffect will watch for the change of the values and run the setFieldValue method when they are modified.

Please follow the CodeSandbox demo. https://codesandbox.io/s/affectionate-mirzakhani-who30?file=/src/App.js

Check this out it may help :

https://github.com/jaredpalmer/formik/issues/1840

you have to call handleChange(e) on-field change!

发布评论

评论列表(0)

  1. 暂无评论