web-dev-qa-db-fra.com

React.js - Erreur de syntaxe: il s'agit d'un mot réservé dans la fonction render ()

Je suis bloqué sur une erreur pour le mot clé réservé "this". Dans mon React Le composant ci-dessous me montre le passage d'un état d'un composant principal "App.js" à mon composant "RecipeList.js" pour mapper les données et restituer chaque composant RecipeItem. I juste ne comprends pas pourquoi je reçois cette erreur

React.js - Erreur de syntaxe: il s'agit d'un mot réservé

L'erreur est appelée dans RecipeList dans la méthode de rendu de rendu. Si quelqu'un pouvait aider, ce serait génial!

Merci

App.js

//main imports
import React, { Component } from 'react';

//helper imports
import {Button} from 'reactstrap'
import RecipeItem from './components/RecipeItem';
import RecipeList from './components/RecipeList';
import './App.css';

const recipes = [
  {
    recipeName: 'Hamburger',
    ingrediants: 'ground meat, seasoning'
  },
  {
    recipeName: 'Crab Legs',
    ingrediants: 'crab, Ole Bay seasoning,'
  }
];

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      recipes
    };
  }

  render() {
    return (
      <div className="App">
        <div className = "container-fluid">
          <h2>Recipe Box</h2>
          <div>
            <RecipeList recipes = {this.state.recipes}/>
          </div>
        </div>
        <div className = "AddRecipe">
          <Button>Add Recipe</Button>
        </div>

      </div>
    );
  }
}

export default App;

RecipeLists.js

import React, {Component} from 'react';
import _ from 'lodash';
import RecipeItem from './RecipeItem';


class RecipeList extends Component {

    renderRecipeItems() {
      return _.map(this.props.recipes, recipeItem => <RecipeItem key = {i} {...recipes} />);
    }

    render() {
      return (
        { this.renderRecipeItems() }
      );
    }
}

export default RecipeList
31
Nickadiemus

Toutes les solutions données ici sont correctes.

Le changement le plus simple consiste à envelopper votre appel de fonction dans un élément JSX:

return (
  <div>
    { this.renderRecipeItems() }
  </div>
)

Cependant, aucune des réponses ne vous dit (correctement) pourquoi le code était cassé en premier lieu.

Pour un exemple plus simple, simplifions un peu votre code.

// let's simplify this
return (
  { this.renderRecipeItems() }
)

tels que le sens et le comportement restent les mêmes. (supprime les parenths et déplace les curlies):

// into this
return {
  this.renderRecipeItems()
};

Ce code contient un bloc, noté {}, dans lequel vous essayez d’appeler une fonction.

En raison de l'instruction return , le bloc {} est traité comme n objet littéral

Un littéral d'objet est une liste de zéro ou plusieurs paires de noms de propriété et des valeurs associées d'un objet, entourées d'accolades ({}).

qui attend soit a: b ou a ( raccourci ) pour ses paires propriété-valeur.

// valid object
return {
  prop: 5
}

// also valid object
const prop = 5;
return {
  prop
}

Cependant, vous passez un appel de fonction à la place, qui n'est pas valide.

return {
  this.renderRecipeItems() // There's no property:value pair here
}

En parcourant ce code, le moteur suppose qu'il lira un littéral d'objet. Quand il atteint le this., il remarque que . n'est pas un caractère valide pour un nom de propriété (sauf si vous l'enveloppiez dans une chaîne - voir ci-dessous) et l'exécution est interrompue ici.

function test() {
  return {
    this.whatever()
    //  ^ this is invalid object-literal syntax
  }
}

test();

Pour démonstration, si vous appelez votre fonction entre guillemets, le code accepterait le . en tant que partie d’un nom de propriété et se briserait maintenant car une valeur de propriété n’est pas fournie:

function test() {
  return {
    'this.whatever()' // <-- missing the value so the `}` bellow is an unexpected token
  }
}

test();

Si vous supprimez l'instruction return, le code ne serait pas interrompu car il s'agirait alors simplement d'un appel de fonction situé dans un bloc :

function test() {
  /* return */ {
    console.log('this is valid')
  }
}

test();

Un problème supplémentaire est que ce n'est pas le moteur JS qui compile votre code, mais bien babel , c'est pourquoi vous obtenez le this is a reserved Word _ erreur au lieu de Uncaught SyntaxError: Unexpected token ..

La raison en est que JSX n'accepte pas les mots réservés du langage JavaScript tels que class et this. Si vous supprimez this, vous pouvez voir que le le raisonnement ci-dessus s'applique toujours - babel essaie d'analyser le code en tant que littéral d'objet possédant une propriété, mais aucune valeur, ce qui signifie que Babel le voit. :

return {
  'renderRecipeItems()' // <-- notice the quotes. Babel throws the unexpected token error
}
63
nem035

Vous pouvez éviter cela en réécrivant RecipeLists.js en tant que composant sans état pur .

En tant que composant pur:

import _ from 'lodash';
import RecipeItem from './RecipeItem';

const RecipeList = props => renderRecipeItems(props);

const renderRecipeItems = ({ recipes }) => _.map(recipes, recipeItem => <RecipeItem key = {i} {...recipes} />);

export default RecipeList;

Alors maintenant, votre composant est fondamentalement juste une fonction avec params.

2
Chase DeAnda

Enveloppez la partie this.renderRecipeItems() avec un div, cela fonctionnera.

La raison pour laquelle elle échouait, est extrêmement bien expliquée par @ nem035 dans ce réponse .

Comme ça:

render () {
   return (
      <div>
         { this.renderRecipeItems() }
      </div>
   );
}

Et je pense au lieu de:

<RecipeItem key = {i} {...recipes} />

CA devrait etre:

<RecipeItem key = {i} {...recipeItem} />

Ce sont les changements que je peux voir, peut-être que d'autres seront nécessaires également.

2
Mayank Shukla