将 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);)。