【问题标题】:JSX for...in loopJSX for...in 循环
【发布时间】:2017-02-12 02:26:00
【问题描述】:

给定这个对象:

lst socials = {
  foo: 'http://foo'
}

我想在 JSX 中循环遍历它。这有效:

let socialLinks = []
let socialBar
for (let social in socials) {
  socialLinks.push(<li>
                     <a alt={social} href={socials[social]}>{ social }</a>
                   </li>)
}
if (socialLinks) {
  socialBar = <div className='align-bottom text-center'>
                <ul className='list-inline social-list mb24'>
                  {socialLinks}
                </ul>
              </div>
}

但这不是(社会未定义):

let socialBar
if (socials) {
  socialBar = <div className='align-bottom text-center'>
                <ul className='list-inline social-list mb24'>
                  for(let social in socials)
                  {<li>
                     <a alt={social} href={socials[social]}>{ social }</a> // social is undefined
                   </li>}
                </ul>
              </div>
}

social 在第二个示例中未定义的原因是什么?我认为内括号存在范围问题,但我没有成功修复它。

我可以用对象键做一个forEach 并像这个post 那样做,但这与我的工作示例没有太大不同。

说清楚 - 我已经成功了,我只是希望在我的第二个示例中更清楚地了解范围问题(或语法错误,如果有的话)。

【问题讨论】:

  • {}包围你的for循环并尝试。虽然它可能会起作用,但通常所做的是使用 .map() 数组方法来获得相同的结果。
  • @DiegoCardoso - 不行。当我尝试时,这会产生语法错误。这很奇怪,因为我认为括号中的东西可以是任何 JS,但它不喜欢 for 循环。在相同的括号中使用map 有效。

标签: javascript reactjs jsx


【解决方案1】:

JSX 只是被转译为React.createElement 的一堆函数调用的糖,您可以在此处找到相关文档:https://facebook.github.io/react/docs/top-level-api.html#react.createelement

ReactElement createElement(
  string/ReactClass type,
  [object props],
  [children ...]
)

基本上你的 JSX 来自

<div style="color: white;">
  <div></div>
</div>

React.createElement('div', { style: { color: 'white' } }, [
  React.createElement('div', {}, [])
])

出于同样的原因,您不能将循环传递给函数中的参数,您也不能将循环放入 JSX。它最终看起来像

React.createElement('div', { style: { color: 'white' } }, [
  React.createElement('div', {}, for (;;) <div></div>)
])

这根本没有意义,因为您不能将 for 循环作为参数传递。另一方面,map 调用返回一个数组,这是 React.createElement 的第三个参数的正确类型。

React 归根结底仍然是一个虚拟 dom 库,但 JSX 只是让它更易于编写。 hyperscript 是 vdom 库的另一个很好的例子,但 JSX 不是标准的。他们在 README 中的示例类似于没有 JSX 的 React:

var h = require('hyperscript')
h('div#page',
  h('div#header',
    h('h1.classy', 'h', { style: {'background-color': '#22f'} })),
  h('div#menu', { style: {'background-color': '#2f2'} },
    h('ul',
      h('li', 'one'),
      h('li', 'two'),
      h('li', 'three'))),
    h('h2', 'content title',  { style: {'background-color': '#f22'} }),
    h('p',
      "so it's just like a templating engine,\n",
      "but easy to use inline with javascript\n"),
    h('p',
      "the intension is for this to be used to create\n",
      "reusable, interactive html widgets. "))

【讨论】:

    【解决方案2】:

    在你的 JSX 中你不能有一个 for 循环。因此,即使您的 for 循环周围有 {},它也不起作用。而是使用如下代码所示的地图。假设您的数据 socials is an array 而不仅仅是一个对象。

    如果社交是您需要使用的对象Object.keys(socials).map(function(key)){}

    class App extends React.Component {
      render() {
        let socialBar = null;
        let socials = [{
      foo: 'http://foo'
    }]
    if (socials) {
      socialBar = <div className='align-bottom text-center'>
                    <ul className='list-inline social-list mb24'>
                      {socials.map(function(social, index) {
                         
                         return <li key={index}>
                         <a alt={index} href={social.foo}>{ social.foo }</a> 
                       </li>
                        
                      }) }
                    </ul>
                  </div>
    }
        return (
          <div>{socialBar}</div>
        )
      }
    
    
    }
    
    ReactDOM.render(<App/>, document.getElementById('app'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.js"></script>
    <div id="app"></div>

    【讨论】:

    • 有这方面的文档吗?我可以看到它不起作用,而 map 确实起作用 - 正如我所说的,我已经让它起作用了,所以我不是在寻找另一种解决方案,而是更深入地了解 jsx/scope 语法。
    • @Yashua JSX 只是被转译为一堆函数调用的糖。它变成了React.createElement(x, y, [React.createElement(x, y, [])]) 之类的东西。出于同样的原因,您不能将循环传递给函数中的参数,也不能将循环放入 JSX。 React 在这种方式上就像超脚本github.com/dominictarr/hyperscript,因为它是一个虚拟 dom 库。 map 调用返回一个数组,这是React.createElement 的第三个参数。作为参数的 for 循环只是像 console.log(for (;;) console.log(hi)) 这样的破坏语法。
    • @AR7 谢谢你,这就是我正在寻找的答案。请张贴作为答案。
    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 2018-11-14
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 2015-02-25
    相关资源
    最近更新 更多