0
votes

problème de mélange des éléments material-ui et du code dans react javascript

J'ai constamment des problèmes en essayant d'utiliser du code et des éléments material-ui dans le code react jsx. Voici un extrait de code:

      y.displayColumn ? (cols+=1) : null)

J'obtiens une erreur d'analyse jsx, lorsque j'ajoute cette ligne ci-dessus:

const icols = 0;
const makeTableRow = (
  x,
  i,
  formColumns,
  handleRemove,
  handleSelect) =>
  <TableRow key={`tr-${i}`}>
    {formColumns.map((y, k) => (
      y.displayColumn ? (<TableCell key={`trc-${k}`}>{x[y.name]}</TableCell>) : null), <-comma added for next line
      y.displayColumn ? (cols+=1) : null)
    )}
    <TableCell>
      <IconButton onClick={() => handleSelect(i)} ><EditIcon fontSize='small'/></IconButton>
      <IconButton onClick={() => handleRemove(i)} ><DeleteForeverIcon fontSize='small' /></IconButton>
    </TableCell>
  </TableRow>

Si je supprime le virgule à l'EOL au-dessus, j'obtiens toujours une erreur. Fondamentalement, je ne peux pas obtenir une carte pour exécuter plus d'une instruction.

Si je supprime la ligne et la virgule EOL au-dessus, tout fonctionne mais je n'obtiens pas le nombre de colonnes affiché, ce que je require.

J'ai essayé d'utiliser un if / else simple avec lequel je suis plus à l'aise, mais je n'ai JAMAIS pu faire fonctionner if / else dans une fonction jsx. Je veux créer une table uniquement pour une colonne avec l'indicateur displayColumn défini sur true, et je veux un compte total des colonnes affichées, afin que je puisse l'utiliser plus tard (cols).

Y a-t-il un moyen d'accomplir cela avec une instruction if / else? Ensuite, je peux avoir plus d'une déclaration dans la clause if. L'opérateur ternaire n'autorise qu'une seule instruction, et je ne trouve nulle part les limitations des cartes.

Merci d'avance pour votre aide!


1 commentaires

essayez ceci: {formColumns.map ((y, k) => {y.displayColumn? (cols + = 1, return trc - $ {k} }> {x [y .name]} ): return null)})}


3 Réponses :


1
votes

Vous pouvez faire quelque chose comme ça. Vous pouvez ouvrir le corps de la fonction de flèche dans la carte et mettre return JSX et y faire l'incrémentation cols . Au lieu d'avoir deux vérifications d'opérateurs ternaires pour la même condition, nous ne pouvons avoir qu'une seule instruction conditionnelle.

<TableRow key={`tr-${i}`}>
  {
    formColumns.map((y, k) => {
      if (y.displayColumn) {
        cols += 1;
        return <TableCell key={`trc-${k}`}>{x[y.name]}</TableCell>
      }
      return null
    })
  }
  <TableCell>
    <IconButton onClick={() => handleSelect(i)} ><EditIcon fontSize='small'/></IconButton>
    <IconButton onClick={() => handleRemove(i)} ><DeleteForeverIcon fontSize='small' /></IconButton>
  </TableCell>
</TableRow>


3 commentaires

Merci abito. Ça a marché. Je jure que j'ai essayé exactement la même chose mais j'ai eu une erreur. Peut-être parce que j'ai utilisé une autre déclaration? Ou vous n'avez pas utilisé de retour? Je veux vraiment comprendre cela parce que je continue de rencontrer le même genre de problèmes.


Heureux d'aider. Cela peut parfois être déroutant.Si vous souhaitez avoir plusieurs instructions à l'intérieur de la carte, vous devez avoir un corps de fonction entre accolades et une instruction return à l'intérieur. S'il s'agit d'un retour conditionnel, fournissez toujours un retour par défaut.


J'ai le même genre de problème ici, en essayant d'insérer du code js parmi les éléments material-ui: stackoverflow.com/questions/62751068/…



1
votes

En gros, je ne peux pas obtenir une carte pour exécuter plus d'une instruction.

Vous ne pouvez pas exécuter plus d'une expression dans une définition de fonction de flèche, utilisez à la place des fonctions déclarées régulières

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="react"></div>

Il n'y a que deux types de fonction de flèche

.success {
  color: darkgreen;
}
.danger {
  color: #5e181b;
}

et

const App = () => {
  return (
    <div>
      <h2>First form</h2>
      <FirstForm true={true} />
      <hr />
      <h2>Second form</h2>
      <SecondForm true={false} />
    </div>
  )
}

const FirstForm = props => {
  // This way is just a ternary conditional
  return (
    <div>
      {props.true
        ? <span className="success">True condition matched</span>
        : <span className="danger">False condition matched</span>
      }
    </div>
  )
}
const SecondForm = props => {
  // This way uses a anonymous function executed in runtime
  return (
    <div>
      {(() => {
        let message = "Hello";
        message += " World, from an auto executed anonymous function";
        return (
        <span className={props.true?"success":"danger"}>{message}</span>
        )
      })()}
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById("react")
);

EDIT 1: Ajouter des conditions entre JSX

Il y a deux façons de le faire

arrow_function = () => {
    // This is a regular logic function
    text = "i will be" + " returned";
    return text;
}
arrow_function = () => "i will be returned"
// This way you declare only one expression after the arrow and it is returned
    {formColumns.map((y, k) => {
      y.displayColumn ? (cols+=1) : null;
      // Return what you want to render
      return y.displayColumn ? (<TableCell key={`trc-${k}`}>{x[y.name]}</TableCell>) : null
    }}

3 commentaires

Cela me montre ce que je ne peux pas faire, ce que j'apprécie. Mais j'ai essayé d'utiliser les fonctions javascript normales. Quand je le fais, j'obtiens des erreurs lorsque j'essaye d'y inclure des éléments material-ui. Pouvez-vous me montrer ce qui fonctionnerait? Je ne peux pas faire fonctionner les instructions if / else avec les éléments / material-ui.


@aaava vous voulez dire que vous voulez des instructions if / else dans jsx? C'est possible.


Eh bien, si c'est le cas, je n'ai pas été en mesure de trouver des exemples de cela sur le Web. J'ai une autre question avec le même type de problème, où je ne peux ajouter aucune déclaration JavaScript à un ensemble d'éléments matériels-UI. Peu importe comment je l'encadre, je reçois des erreurs de syntaxe. Après 20 ans de C # et Java, on pourrait penser que cela ne serait pas si difficile! Même la réponse ci-dessus n'a qu'une déclaration IF. Chaque fois que j'essaie d'ajouter un «autre», j'ai une erreur.



0
votes

Ok psiro, j'ai donc regardé vos exemples, qui fonctionnent tous dans votre situation . Cependant, dès que j'en applique un à mon scénario, j'obtiens toujours une erreur de syntaxe. Comme ici:

<TableBody>
  {(() => {
    console.log('data = ' + data + '.');
    if (data.length > 0) {
    return (data.map((x, i) => row(x, i, formColumns, handleRemove, handleSelect, editIdx)))
  }
  return(<TableRow><TableCell colSpan={`${cols}`}>No Data</TableCell></TableRow>)
  })()}     
</TableBody>

Et c'est le problème que j'ai avec les fonctions anonymes. Ils créent du code non maintenable. Je ne fais rien de différent de votre exemple. Juste DEUX instructions js dans le code que vous avez présenté. Votre code fonctionne, le mien renvoie une erreur de syntaxe.

Et pourquoi ai-je même BESOIN d'une fonction double-anonyme pour avoir 2 simples instructions js dans une instruction if? Pourquoi votre code fonctionne-t-il, et le mien pas?

Addendum:

Ok, j'ai donc fait quelques inférences basées sur votre code et réalisé que j'avais ajouté encore UNE AUTRE fonction anonyme (l'instruction map ) dans le code. Je l'ai retravaillé en ceci, qui a compilé:

  {(() => {
    console.log('data = ' + JSON.Stringify(data, null, 2) + '.');
    if (data.length > 0) {
    return (data.map((x, i) => row(x, i, formColumns, handleRemove, handleSelect, editIdx)))
  }
  return(<TableRow><TableCell colSpan={`${cols}`}>No Data</TableCell></TableRow>)
  })()}

Le fait qu'il semble complètement impossible à entretenir est sans importance, je suppose. Mais ce n'est pas grave car ça ne marche TOUJOURS pas! Maintenant, j'obtiens un 'JSON.stringify n'est pas une fonction' au moment de l'exécution, ce qui est bien sûr ridicule. Pourquoi ne puis-je pas faire fonctionner un simple console.log dans reactjs?

ADDENDUM:

Ok, j'ai résolu le problème grâce à toute l'aide. Pour toute autre personne qui a un problème avec plusieurs instructions dans une fonction anonyme, si vous voulez le faire, vous devez ajouter une instruction return afin que la fonction sache quel résultat retourner.

<TableBody>
  {(() => {
    console.log('data = ' + JSON.Stringify(data, null, 2) + '.'));
    return ((data.length > 0) ? (
    data.map((x, i) => row(
    x,
    i,
    formColumns,
    handleRemove,
    handleSelect,
    editIdx
    ))) : (<TableRow><TableCell colSpan={`${cols}`}>No Data</TableCell></TableRow>) )
  })()}
</TableBody>


2 commentaires

TBH Je n'ai jamais eu de problème qui manipule ces choses, j'aurais besoin de plus de contexte et de jouer avec le code pour voir pourquoi cela ne fonctionne pas. Aussi c'est probablement une faute de frappe mais votre code dit JSON.Stringify au lieu de JSON.Stringify


Ouais, c'était une faute de frappe lors de sa copie. N'était pas dans le code comme ça. J'apprécie vraiment votre aide avec ceci. Je ne suis tout simplement pas un grand fan des fonctions anonymes. Je pense qu'ils rendent le code plus difficile à maintenir, mais je suis évidemment minoritaire! Si vscode avait un meilleur support pour localiser les parenthèses / accolades / etc, cela aiderait probablement.