功能表示组件中的JS代码

时间:2017-05-24 11:19:57

标签: reactjs ecmascript-6

仍在掌握React和ES6。我有以下功能演示组件,工作正常:

const Jobs = (props) => (
  <section id="jobs">
    <div>
      {
        props.jobs.map(job =>
          <div className="job" key={job.slug}>
            <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
            <p>{job.intro}</p>
          </div>
        )
      }
    </div>
  </section>
)

然而,当我尝试在括号之间添加一些额外的JS时,如下所示,我得到有关意外令牌的错误。

const Jobs = (props) => (
  <section id="jobs">
    <div>
      {
        console.log("THIS DOESN'T WORK")
        props.jobs.map(job =>
          <div className="job" key={job.slug}>
            <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
            <p>{job.intro}</p>
          </div>
        )
      }
    </div>
  </section>
)

有人可以解释为什么这不起作用。

5 个答案:

答案 0 :(得分:6)

它与babel is transforming the code into

有关
return <div>{myValue}</div>;

变为

return React.createElement("div", null, myValue);

因此在中间有一个随机console.log,例如

return <div>{
  console.log(myValue);
  myValue
}</div>;

会变成

return React.createElement("div", null, console.log(myvalue); myValue);

显然,这不再是有效的javascript。因此,在JSX转换中唯一有效的是表达式,其值为单个值。

阅读其他答案的一些评论,我发现你实际上是想在你的JSX中做条件逻辑。

为此,您可以选择一些选项。

<强> 1。提取变量

let conditionalValue = "Loading";

if (condition)
  conditionalValue = myValue;

return <div>{conditionalValue}</div>;

<强> 2。提取方法

return <div>{renderValue()}</div>

...

renderValue() {
  if (condition)
    return myValue;

  return "Loading"
}

第3。使用三元

return <div>{condition ? myValue : "Loading"}</div>;

<强> 4。利用布尔评估

如果您希望显示某些内容的后备信息

return <div>{myValue || "Loading"}</div>;

如果您只想根据条件显示某些内容

return <div>{condition && myValue}</div>;

注意:如果您将myValue替换为其他组件,则所有上述示例都同样有效,例如: <p>Hello World</p>

答案 1 :(得分:1)

根据React JSX文档:

  

您可以通过将其包装为卷曲来在JSX中嵌入任何JavaScript表达式   括号

在JS中表达式为:

  

表达式是解析为值的任何有效代码单元。

因此,您不能在单个花括号中放置两个或更多个表达式(console.log是一个表达式,而maping over jobs是第二个表达式)。 @Michael Peyper已经在他的回答中彻底解释了为什么会导致错误。

如果你想在你的例子中使用console.log,你可以将它移动到单独的工具:

const Jobs = (props) => (
  <section id="jobs">
    <div> 
      { console.log("THIS DOESN'T WORK") }
      {
        props.jobs.map(job =>
          <div className="job" key={job.slug}>
            <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
            <p>{job.intro}</p>
          </div>
        )
      }
    </div>
  </section>
)

答案 2 :(得分:1)

正如@thinhvo所说,你不能在return语句中做逻辑。虽然考虑到你的需求,但一个简单的解决办法就是这样。

const Jobs = (props) => {
  let conditionalComp = null;
  if(/*some condition*/ ) {
    conditionalComp = props.jobs.map(job =>
        <div className="job" key={job.slug}>
          <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
          <p>{job.intro}</p>
        </div>
      );
  }
  return (
    <section id="jobs">
      <div>
        {conditionalComp}
      </div>
    </section>
  )
}

答案 3 :(得分:1)

尽量保持回报清洁。尝试在渲染返回之外制作地图和处理。

const Jobs = (props) => {
    console.log("THIS DOESN'T WORK")
    const jobs = props.jobs.map(job =>
        <div className="job" key={job.slug}>
            <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
            <p>{job.intro}</p>
        </div>
    )
    return (
        <section id="jobs">
            <div>
                {jobs}
            </div>
        </section>
    )
}

答案 4 :(得分:0)

实际上你不能用当前的方式做到这一点,第一个console.log("THIS DOESN'T WORK")仍在JSX中,而JSX只会理解react的元素或DOM。

因此,如果你想做额外的JS,请在map函数内部(返回值之前)执行:

<div>
  {
    props.jobs.map((job) => {
      console.log("something here");
      return (
        <div className="job" key={job.slug}>
          <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
          <p>{job.intro}</p>
        </div>
      )
    }
    )
  }
</div>

=====

您是否注意到我添加了(){}?事实上,这是我们在ES6中编写的方式,使用=>将函数词汇绑定到当前的反应组件。

您之前的代码props.jobs.map( job => <div> </div> )只是一种快速返回某些JSX元素的方法(div

=====

ADDED VERSION :为映射执行逻辑(条件):

const Jobs = (props) => {
  let returned_jsx = (<div>No Job!</div>);
  if (props.jobs.length) { // or whatever condition you need!
    returned_jsx = (
      <section id="jobs">
        <div>
          {
            props.jobs.map(job =>
              <div className="job" key={job.slug}>
                <p><strong>{job.title} at <Link to={"/jobs/" + job.slug}>{job.company}</Link></strong></p>
                <p>{job.intro}</p>
              </div>
            )
          }
        </div>
      </section>
    )
  }
  return returned_jsx;
}    

上面的代码只是一个关于如何在JSX中返回不同内容的逻辑的示例。如果您仍有错误,请在此处发布,我们将进一步讨论,谢谢