web-dev-qa-db-fra.com

Comment définir / modifier la valeur du champ à partir d'une action de l'utilisateur externe ???? React Final Form

Il existe de nombreuses situations dans lesquelles nous pourrions vouloir définir la valeur d'un champ spécifique dans un formulaire pour aider l'utilisateur.

Par exemple, une boutique de fruits en ligne peut demander aux utilisateurs combien de pommes ils souhaitent acheter. Pour aider les utilisateurs, nous pourrions avoir 3 boutons tels que

  • "minimum" - définit la valeur du champ à la quantité minimale que le magasin peut vendre
  • "maximum" - idem, mais pour max
  • "ce que j'ai acheté la dernière fois" - définit la valeur du champ à la quantité de pommes que l'utilisateur a achetée la dernière fois

Après avoir parcouru ce que je pensais être les deux exemples les plus pertinents ( chargement et initialisation des valeurs et champs calculés ), je ne peux toujours pas comprendre celui-ci sans devenir trop hacky.

Comment pouvons-nous définir la valeur d'un champ à partir de l'action d'un utilisateur (comme en cliquant sur un bouton)?

17
aryzing

Erik a un merveilleux post sur les mutateurs , qui m'a inspiré pour trouver la solution que je cherchais:

<Form
  mutators={{
    setMin: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 1)
    },
    setMax: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 100)
    },
    setLast: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 6)
    },
  }}

  render={({ mutators, ...rest }) => (
    <>
      <button onClick={mutators.setMin}>minimum apples</button>
      <button onClick={mutators.setMax}>maximum apples</button>
      <button onClick={mutators.setLast}>what I bought last time</button>
    </>
  )}
/>
25
aryzing

La réponse acceptée est excellente et m'a conduit à ma solution, mais au cas où quelqu'un viendrait ici comme je l'ai fait pour chercher un moyen de modifier les valeurs de champ de l'extérieur de React application =, vous pouvez le faire en créant un mutateur complètement générique qui définit n'importe quel champ à n'importe quelle valeur, et en obtenant une référence globale au mutateur lié sous la forme comme ceci

<Form
  mutators={{
    // expect (field, value) args from the mutator
    setValue: ([field, value], state, { changeValue }) => {
      changeValue(state, field, () => value)
    }
  }}
  render={({ mutators, ...rest }) => {
    // put the reference on a window variable of your choice here
    if (!window.setFormValue) window.setFormValue = mutators.setValue

    return (
      <>
        <Field name="field1">...</Field>
        <Field name="field2">...</Field>
        ...
      </>
    )
  }}
/>

// somewhere else, outside of the React application

window.setFormValue('field1', 'value1')
window.setFormValue('field2', 'value2')

Disclaimer: Le modèle ci-dessus ne doit pas être utilisé sauf en cas d'absolue nécessité, pour des cas d'utilisation très particuliers. Par exemple, je l'utilise pour automatiser le remplissage de champs à partir de code qui doit être externe à mon React app . Vous ne devriez pas faire cela pour le code d'application réel. Mais si vous en avez besoin, cela fonctionne très bien!

8
davnicwil