React-Final-Form как передать props location.search для работы

Последние несколько дней я использую React-Final-Form, но у меня много проблем.

В моей основной функции PasswordReset мне нужно взять опору location.search и передать ее пользовательскому handleSubmitOnClick, чтобы обработать результат при отправке.

Здесь основная функция:

const handleSubmitOnClick = ({ // I need the location.search to be passed here as prop
  password,
  password_confirmation,
}) => {

  const url = 'http://localhost:3000/api/v1/users/passwords';

  const headers = {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    }
  }

  const data = {
    "user": {
      "reset_password_token": location.search,
      "password": password,
      "password_confirmation": password_confirmation,
    }
  }

  axios.post(url, data, headers)
  .then(response => console.log(response))
  .catch(error => console.log('error', error)))
}

const PasswordReset = ({
  location //<==== I need to pass this to 'handleSubmitOnClick' function
}) => 
  <Fragment>
    <h1>Password Reset page</h1>

    <Form 
      onSubmit={handleSubmitOnClick}
      decorators={[focusOnError]}
    >
      {
        ({ 
          handleSubmit, 
          values, 
          submitting,
        }) => (
        <form onSubmit={handleSubmit}>         

          <Field 
            name='password'
            placeholder='Password'
            validate={required}
          >
            {({ input, meta, placeholder }) => (
              <div className={meta.active ? 'active' : ''}>
                <label>{placeholder}</label>
                <input {...input} 
                  type='password' 
                  placeholder={placeholder} 
                  className="signup-field-input"

                />
                {meta.error && meta.touched && <span className="invalid">{meta.error}</span>}
                {meta.valid && meta.dirty && <span className="valid">Great!</span>}
              </div>
            )}
          </Field>

          <Field 
            name='password_confirmation'
            placeholder='Confirm password'
            validate={required}
          >
            {({ input, meta, placeholder }) => (
              <div className={meta.active ? 'active' : ''}>
                <label>{placeholder}</label>
                <input {...input} 
                  type='password' 
                  placeholder={placeholder} 
                  className="signup-field-input"

                />
                {meta.error && meta.touched && <span className="invalid">{meta.error}</span>}
                {meta.valid && meta.dirty && <span className="valid">Great!</span>}
              </div>
            )}
          </Field>

          <button 
            type="submit"
            className="signup-button"
            disabled={submitting}
          >
            Submit
          </button>
        </form>
      )}
    </Form>
  </Fragment>

export default PasswordReset;

Любая помощь ДЕЙСТВИТЕЛЬНО приветствуется. Лучше плохой ответ, чем отсутствие ответов. Заранее спасибо.


person Joe    schedule 27.09.2019    source источник


Ответы (2)


Вы можете каррировать свою функцию, чтобы location обновлялась каждый раз.

Метод каррирования: (предпочитается линтером)

const handleSubmitOnClick = (location) => ({ //location would come from PasswordReset every time there's a re-render
                             ^^^^^^^^
  password,
  password_confirmation,
}) => {
   ...
}

const PasswordReset = ({
  location //<==== I need to pass this to 'handleSubmitOnClick' function
}) => 
  <Fragment>
    <h1>Password Reset page</h1>

    <Form 
      onSubmit={handleSubmitOnClick(location)} // <--- This will update location on every re-render
      decorators={[focusOnError]}
    >
      { ... }
    </Form>
  </Fragment>

export default PasswordReset;

Метод встроенной функции:

В качестве альтернативы вы можете использовать другой предоставленный ответ, но вам все равно нужно обновить функцию handleSubmitOnClick, чтобы принять вашу location опору. Он будет создавать новую функцию при каждом повторном рендеринге, но поскольку линтеры считают встроенные функции плохой практикой, я предпочитаю метод каррирования.

   <Form 
      onSubmit={() => handleSubmitOnClick(location)} // <--- This will create new function on every re-render
      decorators={[focusOnError]}
    >
person Rikin    schedule 27.09.2019
comment
Это то, что будет делать каррирование: он будет обновлять функцию с новым местоположением при каждом рендеринге, аналогично вашему ответу, где вы вместо этого создаете новую функцию при каждом рендеринге. - person Rikin; 27.09.2019
comment
Сделал свое дело. Моя ошибка заключалась в том, чтобы поместить местоположение в деконструированную область handleSubmitClick, где находятся значения. - person Joe; 27.09.2019
comment
Привет, Рикин, не могли бы вы (или кто-нибудь еще) взглянуть на эту проблему, с которой я боролся в течение нескольких недель? stackoverflow.com/questions/58015594/ .... любое решение очень приветствуется. Я пробовал dataForm, я пробовал новый Blob ... всегда возвращает кучу ошибок - person Joe; 27.09.2019

<Form 
  onSubmit={() => handleSubmitOnClick(location)}
  decorators={[focusOnError]}
>

Оберните его в анонимную функцию, которая после вызова вызывает вашу функцию с требуемым параметром, который в данном случае будет location.

После этого у функции будет дополнительный аргумент:

handleSubmitOnClick = location => ({..props})
person bamtheboozle    schedule 27.09.2019
comment
handleSubmitOnClick не принимает location, а скорее разрушает password и password_confirmation, поэтому его также необходимо обновить, это не полное решение (пока) - person Rikin; 27.09.2019
comment
поэтому обновите функцию handleSubmitOnClick, чтобы она принимала местоположение ..? - person bamtheboozle; 27.09.2019
comment
Да, это то, чего вам не хватало для полного решения. - person Rikin; 27.09.2019