【问题标题】:Giving unique key's to <li>'s inside of nested .map functions为嵌套 .map 函数内部的 <li> 赋予唯一键
【发布时间】:2018-05-09 21:07:42
【问题描述】:

我有一个需要嵌套映射函数才能工作的函数。这是因为我正在构建一个矩阵网格问题表格。首先是问题,从一个数组映射,然后是嵌套的.map 函数,用于该问题的可能选择。

这适用于第一行问题。问题是我分配的所有Choices(即同意、不同意等)的id 只是1, 2, 3, or 4。然后这与下一个问题重复。

因此,第一个问题之后的所有问题,在选择选项时只会影响第一个问题。我需要一种方法来继续增加 id 数字。

这是一个例子:

Question 1: {id}'s to assign: 1, 2, 3, 4
Question 2: {id}'s to assign: 5, 6, 7, 8 etc...

这是相关的sn-p代码。 params 是一个包含 2 个数据数组 SubFieldsChoices 的对象,它们是我映射的对象。

renderFieldlikert(params) {
    let matrixQuestion = params.SubFields.map(function(o, x) {
      let questionText = (<li className='left-column'><h4 className='text-left'>{o.Label}</h4></li>);
      let radioButtons = params.Choices.map(function(y, i) {
        let v = y.Score
        return(
          <li className='animated fadeIn'>
            <input onChange={(e) => this.props.handleRadioChange(o.ID, e)} type="radio" name={o.Label} id={i} key={i} value={v} />
            <label htmlFor={i}>{y.Score}</label>
          </li>
        )
      }.bind(this));

【问题讨论】:

  • 您不需要增加 id,而是需要为每个键设置 unique id。一种解决方法是导入像 uuid 这样的库,并使用它在每次迭代中生成值。
  • 我不知道你为什么需要这些 id,但很多人忽略了这样一个事实,即你可以通过使用 this 来判断处理函数内部与哪个元素进行了交互。
  • 我需要唯一的id,以便我的&lt;label&gt; 可以指向正确的&lt;input&gt; 字段。由于我迭代第二个.map 函数的次数与SubFields 的次数一样多(即问题),我需要找到一种方法来使数字独一无二。否则,所有问题的所有选项agree, disagree, strongly agree, strongly disagree 将是相同的1,2,3 or 4。请参阅下面的答案。诀窍只是使用一个简单的计数器并递增

标签: javascript reactjs key unique array.prototype.map


【解决方案1】:

一个简单的计数器变量就可以解决问题。

renderFieldlikert(params) {
var count = 0;
let matrixQuestion = params.SubFields.map(function(o, x) {
  let questionText = (<li className='left-column'><h4 className='text-left'>{o.Label}</h4></li>);
  let radioButtons = params.Choices.map(function(y, i) {
    count++;
    let v = y.Score;
    return(
      <li className='animated fadeIn'>
        <input onChange={(e) => this.props.handleRadioChange(o.ID, e)} type="radio" name={o.Label} id={count} key={count} value={v} />
        <label htmlFor={count}>{y.Score}</label>
      </li>
    );
  }.bind(this));

请注意,这会破坏地图函数的纯功能性质(即,它是一种副作用)。您可能需要考虑切换到旧的 for 循环。

另外,由于内部map 始终在相同长度的数组上执行,您可以显式计算索引。

renderFieldlikert(params) {
let matrixQuestion = params.SubFields.map(function(o, x) {
  let questionText = (<li className='left-column'><h4 className='text-left'>{o.Label}</h4></li>);
  let radioButtons = params.Choices.map(function(y, i) {
    var count = params.Choices.length*x + i + 1;
    let v = y.Score;
    return(
      <li className='animated fadeIn'>
        <input onChange={(e) => this.props.handleRadioChange(o.ID, e)} type="radio" name={o.Label} id={count} key={count} value={v} />
        <label htmlFor={count}>{y.Score}</label>
      </li>
    );
  }.bind(this));

【讨论】:

  • 是的,我只是想说这有效,但必须在 htmlFor 中包含 count。至于第二个补充。由于我不明白的原因,我无法访问x,这是第一个.map 函数中的index。我不知道为什么,无论哪种方式,您发布的第一个答案都很好。谢谢!
猜你喜欢
  • 2011-10-05
  • 2022-10-03
  • 2012-01-10
  • 2018-11-15
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
相关资源
最近更新 更多