仍在掌握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>
)
有人可以解释为什么这不起作用。
答案 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中返回不同内容的逻辑的示例。如果您仍有错误,请在此处发布,我们将进一步讨论,谢谢