Skip to content

How to avoid looping if two fields change each other's values? #9

@INQTR

Description

@INQTR

I need to change the value of the give field if the value of the resave field changes and vice versa.

here is an example of my code:

import React from 'react';
import { Form, Field } from 'react-final-form';
import { OnChange } from 'react-final-form-listeners';

import RenderField from '../../components/Forms/FieldRender';
import FieldBtns from '../../components/Forms/FieldBtns';
// import AutoSave from '../../components/Forms/AutoSave';

const WhenFieldChanges = ({
  field,
  becomes,
  set,
  to,
}) => (
  <Field name={set} subscription={{}}>
    {(
      // No subscription. We only use Field to get to the change function
      { input: { onChange } },
    ) => (
      <OnChange name={field}>
        {() => {
          if (becomes) {
            onChange(to);
          }
        }}
      </OnChange>
    )}
  </Field>
);

let prevGiveCurrency;
let prevReceiveCurrency;

let prevGive;
let prevReceive;

const ExchangeForm = ({
  onSubmit,
  pairs,
  exchangeSetFrom,
  exchangeSetTo,
  price,
}) => (
  <div>
    <Form
      onSubmit={onSubmit}
      initialValues={{
        give: 0,
        receive: 0,
        giveCurrency: 'BTC',
        receiveCurrency: 'USD',
      }}
      // validate={(values) => {
      //   const errors = {};
      //   return errors;
      // }}
      render={({
        handleSubmit,
        submitting,
        values,
      }) => {
        prevGive = values.give;
        prevReceive = values.receive;

        if (prevGiveCurrency !== values.giveCurrency) {
          exchangeSetFrom(values.giveCurrency);
        }
        prevGiveCurrency = values.giveCurrency;

        if (prevReceiveCurrency !== values.receiveCurrency) {
          exchangeSetTo(values.receiveCurrency);
        }
        prevReceiveCurrency = values.receiveCurrency;

        return (
          <form onSubmit={handleSubmit}>
            {/* <AutoSave debounce={0} save={onSubmit} /> */}

            <WhenFieldChanges
              field="give"
              becomes={price}
              set="receive"
              to={values.give * price}
            />

            <WhenFieldChanges
              field="receive"
              becomes={price && values.receive !== prevReceive}
              set="give"
              to={values.receive * price}
            />

            <div className="form__field exchange__field">
              <label htmlFor="give" className="form__field-label">I give</label>
              <Field
                id="give"
                name="give"
                component={RenderField}
                type="text"
                placeholder={0}
              />
              <div className="form__field-select">
                <Field name="giveCurrency" component="select">
                  {pairs.map(pair => (
                    <option key={pair.fromSymbol} value={pair.fromSymbol}>{pair.fromSymbol}</option>
                  ))}
                </Field>
              </div>
            </div>
            <div className="form__field exchange__field">
              <label htmlFor="receive" className="form__field-label">I receive</label>
              <Field
                id="receive"
                name="receive"
                component={RenderField}
                type="text"
                placeholder={0}
              />
              <div className="form__field-select">
                <Field name="receiveCurrency" component="select">
                  {pairs.find(e => e.fromSymbol === values.giveCurrency)
                  && pairs.find(e => e.fromSymbol === values.giveCurrency).toSymbols.map(symbol => (
                    <option key={symbol} value={symbol}>{symbol}</option>
                  ))}
                </Field>
              </div>
            </div>
            <div className="form__btns exchange__btns">
              <FieldBtns
                type="submit"
                colorBtn="btn-success"
                sizeBtn="middle"
                classBtn="btn-login"
                translate="Exchange"
                disabled={submitting}
              />
            </div>
            <pre>{JSON.stringify(values, 0, 2)}</pre>
          </form>
        );
      }}
    />
  </div>
);

export default ExchangeForm;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions