React.js - 语法错误:这是 render() 函数中的保留字

IT技术 javascript reactjs babeljs
2021-03-06 16:18:35

我遇到了保留关键字“this”的错误。在下面的 React 组件中,我将一个状态从我的主要组件“App.js”传递到我的“RecipeList.js”组件,然后映射数据并呈现每个 RecipeItem 组件。我只是不明白为什么我会收到这个错误

React.js - 语法错误:这是一个保留字

该错误在渲染返回方法内的 RecipeList 中调用;如果有人可以提供帮助,那就太好了!

谢谢

应用程序.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;

食谱列表.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
3个回答

这里给出的所有解决方案都是正确的。

最简单的更改是将您的函数调用包装在 JSX 元素中:

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

但是,没有一个答案(正确地)告诉您为什么代码首先被破坏。

为了更简单的例子,让我们稍微简化一下你的代码

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

以至于意义和行为仍然相同。(删除括号并移动curl):

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

这段代码的作用是它包含一个由 表示的块,{}您试图在其中调用一个函数。

由于该return语句,块{}被视为对象字面量

对象字面量是一个包含零对或多对属性名称和对象关联值的列表,用花括号 ({}) 括起来。

它的属性-值对需要a: bor a简写)语法。

// valid object
return {
  prop: 5
}

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

但是,您正在传递一个函数调用,这是无效的。

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

在执行此代码时,引擎假定它将读取对象字面量。当它到达 时this.,它注意到这.不是属性名称的有效字符(除非您将其包装在字符串中 - 见下文)并且执行在此处中断。

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

test();

为了演示,如果您将函数调用括在引号中,代码将接受.作为属性名称的一部分并且现在会中断,因为未提供属性值:

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

test();

如果删除该return语句,则代码不会中断,因为那将只是内的函数调用

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

test();

现在,另一个问题是编译您的代码的不是 JS 引擎,而是babel,这就是为什么您收到this is a reserved word错误而不是Uncaught SyntaxError: Unexpected token ..

原因是 JSX 不接受来自 JavaScript 语言的保留字,例如classthis如果您删除this,您可以看到上面推理仍然适用- babel 尝试将代码解析为具有属性但没有值的对象文字,这意味着 babel 会看到:

return {
  'renderRecipeItems()' // <-- notice the quotes. Babel throws the unexpected token error
}
老哥非常感谢。通读几遍后,这更有意义。我意识到为什么我的 JSX 在我发布后不久没有运行,但现在我知道为什么了。又是人。谢谢!
2021-04-17 16:18:35
@Nickadiemus 很高兴为您提供帮助 :)
2021-04-19 16:18:35

用 包裹this.renderRecipeItems()零件div,它将起作用。

@nem035 在这个答案中很好地解释了它失败的原因

像这样:

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

我认为而不是:

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

它应该是:

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

这些是我可以看到的更改,可能还需要其他一些更改。

它不是返回的数组,而是一个无效的对象文字,其中包含一个函数调用
2021-04-20 16:18:35
@nem035 抱歉,没明白你能解释更多“这是一个带有函数 cal 的无效对象文字”在哪里?
2021-04-23 16:18:35
是否澄清了一点?如果您用正确的行为替换了不正确的“返回数组”部分,我很高兴删除我的答案并支持您的答案。
2021-05-08 16:18:35
@nem035 我会更新我的答案,但不要删除你的答案它解释了很多事情,真的很棒的人需要知道这一点,如果你删除它将不可见,现在我想我应该删除我的答案:)
2021-05-13 16:18:35
评论可能太长了,我添加了一个补充答案
2021-05-14 16:18:35

您可以通过重写RecipeLists.js纯无状态组件来避免这种情况

作为纯组件:

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;

所以现在你的组件基本上只是一个带有参数的函数。

太感谢了!
2021-04-24 16:18:35