1
votes

event.currentTarget.name retournant en tant que currentTarget

J'ai une fonction handleChange en typographie que j'appelle dans une autre fonction pour envoyer la valeur des changements dans un champ de texte à un arbre mobx. Cependant, lorsque je définis const {name} = event.currentTarget et que je le consigne plus tard dans la fonction, la variable name revient en tant que 'currentTarget' au lieu de l'attribut name que j'attribue dans ma fonction renderHexTextField , et la valeur n'est pas définie.

Je rend un certain nombre de champs de texte différents en appelant la fonction renderHexTextField, qui prend en deux paramètres. Le premier est la valeur de

Si cela fonctionnait comme prévu, la variable name serait égale à la chaîne 'hoverFontColor' de mon instruction return, qui serait ensuite passée dans handleChange en tant que clé pour l'objet css , et value manipulerait l'arborescence d'état de mobx.

Toute aide est appréciée!

edit ** J'ai oublié de mentionner que le composant TextField est un MaterialUI composant

SOLUTION EDIT ** - Mon handleChange était lié à un anti-rebond. J'ai dû mettre à jour mon attribut de composant onChange pour que event.persist () soit exécuté avant this.handleChange. Merci Praveen et Chris!

return (
   this.renderHexTextField(css.hoverFontColor, 'hoverFontColor')
)


  private renderHexTextField(input: string, name: string) {
    // name parameter used to specify which state in handleChange function
    if (name === 'fontType' || this._throwHexErr(input) === 'True') {
      // If hex format is correct, render normal text field
      return (
        <TextField
          required={true}
          id="standard-required"
          margin="normal"
          name={name}
          placeholder={input}
          onChange={this.handleChange}
        />
      )
    } else {
      // else render error text field
      return (
        <TextField
          error={true}
          id="standard-error"
          margin="normal"
          name={name}
          placeholder={input}
          onChange={this.handleChange}
        />
      )
    }
  }

  private handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const { name, value } = event.currentTarget
    const { store } = this.props
    const currentBot = store.bots.current
    if (currentBot) {
      const id = currentBot._id
      const css: any = toJS(currentBot.theme.css)
      log('css obj >> ', css)
      if (css) {
        css[name] = value
        log('handleChange >>> ', name, value, css)
        currentBot.patchCSS(id, css)
      }
    } else {
      log('No current bot in handleChange')
    }
  }

  private _validateHex(hexcode: string, regex: any) {
    // Regex Testing Function
    log('validating hex')
    return regex.test(hexcode)
  }

  private _throwHexErr(userInput: string) {
    // Return True or Error depending on result of Regex Test
    const regex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
    if (this._validateHex(userInput, regex)) {
      return 'True'
    } else {
      return 'Error'
    }
  }


0 commentaires

3 Réponses :


1
votes

Je pense que vous devez remplacer

<TextField
          error={true}
          id="standard-error"
          margin="normal"
          name={name}
          placeholder={input}
          onChange={(event) => this.handleChange(event)}
        />

par

private handleChange = (event: any): void => {
    const name = event.target.name;
    const value = event.target.value;
    const { store } = this.props
    const currentBot = store.bots.current
    if (currentBot) {
      const id = currentBot._id
      const css: any = toJS(currentBot.theme.css)
      log('css obj >> ', css)
      if (css) {
        css[name] = value
        log('handleChange >>> ', name, value, css)
        currentBot.patchCSS(id, css)
      }
    } else {
      log('No current bot in handleChange')
    }
  }

ou

const name = event.target.name;
const value = event.target.value;

Cela devrait fonctionner correctement

const { name, value } = event.target

aussi, faites

const { name, value } = event.currentTarget


10 commentaires

Salut Praveen, j'ai essayé cela, et j'obtiens une erreur de typographie indiquant que Type 'EventTarget & HTMLInputElement' ne peut pas être utilisé comme type d'index. Assez nouveau dans le typographie - dois-je définir une interface dans le document?


(event: any) devrait corriger cela


Ainsi, après avoir modifié (event: any) et défini le nom et la valeur égaux à event.target.name et event.target.value, j'obtiens une erreur indiquant que event.target est nul: TypeError: Impossible de lire la propriété 'nom' de null


J'ai également essayé de créer un attribut personnalisé sur le composant TextField appelé data-name, mais je rencontre la même erreur lorsque je tape dans le TextField que event.target est nul


Même erreur. J'ai également inclus event.persist () dans la fonction handleChange


@MatthewPorter J'ai modifié ma réponse, veuillez essayer ceci


haha .... c'est comme la première étape pour apprendre à faire des événements onChange. Je ne peux pas croire que j'ai oublié ça. laissez-moi l'essayer.


Eh bien, j'ai résolu le problème de nom en ajoutant un paramètre de nom et en passant le nom de la fonction parent. Mais ce n'est qu'une solution de contournement, car je rencontre toujours la même erreur pour event.target.value


J'ai compris - mon handleChange était lié à un anti-rebond, et il essayait de mettre à jour l'arborescence des états avant la fin du anti-rebond. Je pense.


J'ai donc dû ajouter event.persist () dans mon attribut onChange avant d'appeler handleChange



1
votes

J'ai eu le même problème récemment, j'ai utilisé React.FormEvent . Cela me donne event.currentTarget.name depuis l'interface. Cela vous aide-t-il?

Pour préciser, essayez de remplacer React.ChangeEvent par React.FormEvent .


4 commentaires

Merci Chris mais malheureusement cela n'a pas fonctionné. J'utilise Material UI et il semble que TextField attend un type de React.ChangeEvent. Peut-être que je peux le modifier dans le fichier d.ts?


J'éviterais de changer le fichier .d.ts. Je ne suis pas familier avec Material UI, mais j'ai l'impression que vous êtes dans la bonne direction. Et target au lieu de currentTarget semble correspondre à la documentation material-ui. Utilisez-vous du code Visual Studio? Si vous survolez onChange sur le composant, cela vérifie-t-il que l'événement doit avoir le type React.ChangeEvent ? Il se peut que material-ui vous fournisse un type personnalisé à utiliser à la place.


Oui, il vérifie React.ChangeEvent. Je vais jeter un autre regard sur la documentation de l'API TextField


Je pense que vous êtes dans la bonne direction. J'éviterais d'utiliser «n'importe quel» type, c'est une trappe d'évacuation et ça va à l'encontre de l'intérêt d'utiliser un système de typage. Si tout échoue et que le code fonctionne, il serait préférable de créer une interface correspondante que vous possédez, qui décrit les types que vous attendez. Au moins, si vous faites un changement sur toute la ligne, cela vous évitera de faire une erreur



0
votes

Voir la modification de ma solution ci-dessus. Ma fonction handleChange était liée à un anti-rebond, j'ai donc dû inclure event.persist () dans l'attribut onChange.


0 commentaires