将 jsx 放入 class 组件方法时出现 React-jsx 语法错误
React-jsx syntax error when putting jsx into a class components method
在 React class 组件中,我正在编写一个构建 <select>
下拉列表的方法,但 Babel 出现错误。该错误是由于第一个 <select>
标记未关闭引起的。我想不出正确的 react-jsx 语法。
在下面的代码中,我试图将创建 <select>
的代码封装到组件 class 中的另一个方法中。如果我有这个函数,只需构建选项并将 <select>
和 </select>
放在该函数周围(在渲染方法中)它就可以工作,但我想将选定的值放入 <select>
标记而不是使用 if 语句,并将它们放在一起。
正确的语法是什么?
谢谢...
注释指向问题行的代码:
render()
{
function buildQtyOptions(isAvailable, qty)
{
var opts = [];
if(!isAvailable)
{
opts.push(<td></td>);
return opts;
}
{/* Uncommenting this next line causes the error because the select is unclosed */}
{/* opts.push(<select>) */}
for (var i=1; i < 11; i++)
{
if(i === parseInt(qty))
{
opts.push(<option value={i} selected>{i}</option>);
}
else
{
opts.push(<option value={i}>{i}</option>);
}
}
{/* opts.push(</select>); */}
return opts;
}
{/* Other methods omitted here */}
return(
<tr>
<td>{getImage(this.props.available)}</td>
<td>{this.props.name}</td>
<td>
{/* I want to move this and the closing select into the buildQtyOptions method */}
{/*<select> */}
{ buildQtyOptions(this.props.available, this.props.years) }
{/*</select> */}
</td>
</tr>);
尝试使用 map
而不是使用 for
循环一次完成所有操作,如下所示:
opts.push(
<select>
{ [...Array(10).keys()].map(x => x + 1).map((i) => {
if (i == parseInt(qty)) {
return <option value={i} key={i} selected>{i}</option>;
} else {
return <option value={i} key={i}>{i}</option>;
}
});
}
</select>
);
生成数字范围的 [...Array(10).keys()]
技巧来自 this answer。第一个 map
只是简单地偏移范围,以便您获得从 1 到 10 而不是从 0 到 9 的数字,第二个实际上生成 <option>
分量。之所以可行,是因为将组件的所有子组件作为数组一次传递是有效的。
你不能按照你想要的方式做到这一点的原因是每对闭合的 JSX 标签都被翻译成一个 React.createElement
调用,所以如果你不关闭 JSX 标签,JSX 编译器有不知道什么时候打电话 React.createElement
.
JSX 并不是真正的标记,它是函数调用的语法糖。
<select></select>
变成
React.createElement('select');
也许这有助于理解为什么不能真正将打开和关闭分开 "tags"。我猜你 可以 认为它们等同于括号。
相反你可以做
return <select>{opts}</select>;
(转换为 return React.createElement('select', null, opts);
)。
在 React class 组件中,我正在编写一个构建 <select>
下拉列表的方法,但 Babel 出现错误。该错误是由于第一个 <select>
标记未关闭引起的。我想不出正确的 react-jsx 语法。
在下面的代码中,我试图将创建 <select>
的代码封装到组件 class 中的另一个方法中。如果我有这个函数,只需构建选项并将 <select>
和 </select>
放在该函数周围(在渲染方法中)它就可以工作,但我想将选定的值放入 <select>
标记而不是使用 if 语句,并将它们放在一起。
正确的语法是什么?
谢谢...
注释指向问题行的代码:
render()
{
function buildQtyOptions(isAvailable, qty)
{
var opts = [];
if(!isAvailable)
{
opts.push(<td></td>);
return opts;
}
{/* Uncommenting this next line causes the error because the select is unclosed */}
{/* opts.push(<select>) */}
for (var i=1; i < 11; i++)
{
if(i === parseInt(qty))
{
opts.push(<option value={i} selected>{i}</option>);
}
else
{
opts.push(<option value={i}>{i}</option>);
}
}
{/* opts.push(</select>); */}
return opts;
}
{/* Other methods omitted here */}
return(
<tr>
<td>{getImage(this.props.available)}</td>
<td>{this.props.name}</td>
<td>
{/* I want to move this and the closing select into the buildQtyOptions method */}
{/*<select> */}
{ buildQtyOptions(this.props.available, this.props.years) }
{/*</select> */}
</td>
</tr>);
尝试使用 map
而不是使用 for
循环一次完成所有操作,如下所示:
opts.push(
<select>
{ [...Array(10).keys()].map(x => x + 1).map((i) => {
if (i == parseInt(qty)) {
return <option value={i} key={i} selected>{i}</option>;
} else {
return <option value={i} key={i}>{i}</option>;
}
});
}
</select>
);
生成数字范围的 [...Array(10).keys()]
技巧来自 this answer。第一个 map
只是简单地偏移范围,以便您获得从 1 到 10 而不是从 0 到 9 的数字,第二个实际上生成 <option>
分量。之所以可行,是因为将组件的所有子组件作为数组一次传递是有效的。
你不能按照你想要的方式做到这一点的原因是每对闭合的 JSX 标签都被翻译成一个 React.createElement
调用,所以如果你不关闭 JSX 标签,JSX 编译器有不知道什么时候打电话 React.createElement
.
JSX 并不是真正的标记,它是函数调用的语法糖。
<select></select>
变成
React.createElement('select');
也许这有助于理解为什么不能真正将打开和关闭分开 "tags"。我猜你 可以 认为它们等同于括号。
相反你可以做
return <select>{opts}</select>;
(转换为 return React.createElement('select', null, opts);
)。