2017-08-06 34 views
1

我想通过React中的某些元素循环,因为我需要渲染每个视图的数组的一部分。在React中循环遍历某些元素

数组渲染必须从ArrayIndexStart开始,并以ArrayIndexEnd结束。

这里是我的了:

var ObjectArray =[{"letter":"a"},{"letter":"b"},{"letter":"c"},{"letter":"d"},{"letter":"e"},{"letter":"f"},{"letter":"g"},{"letter":"h"},{"letter":"i"},{"letter":"j"},{"letter":"k"},{"letter":"l"},{"letter":"ł"},{"letter":"m"},{"letter":"n"},{"letter":"ń"},{"letter":"o"},{"letter":"ó"},{"letter":"p"},{"letter":"q"},{"letter":"r"},{"letter":"s"},{"letter":"ś"},{"letter":"t"},{"letter":"u"},{"letter":"v"},{"letter":"w"},{"letter":"x"},{"letter":"y"},{"letter":"z"},{"letter":"ź"},{"letter":"ż"}]; 
 

 
class ImageViewer extends React.Component { 
 
    constructor() { 
 
     super(); 
 
     this.state = { 
 
      ArrayIndexStart: 0, 
 
      ArrayIndexEnd: 8, 
 
     } 
 
     this.handleButtonLeft = this.handleButtonLeft.bind(this); 
 
     this.handleButtonRight = this.handleButtonRight.bind(this); 
 
    } 
 
    handleButtonLeft(ArrayIndexStart, ArrayIndexEnd, event) { 
 
     if (ArrayIndexStart >= 8) { 
 
      this.setState({ ArrayIndexEnd: ArrayIndexEnd,ArrayIndexStart: ArrayIndexStart}) 
 
     } 
 
     else { 
 
      this.setState({ ArrayIndexEnd: 8,ArrayIndexStart: 0 }) 
 
     } 
 
    } 
 
    handleButtonRight(ArrayIndexStart, ArrayIndexEnd, event) { 
 
     if (ArrayIndexEnd <= ObjectArray.length) { 
 
      this.setState({ ArrayIndexStart: ArrayIndexStart,ArrayIndexEnd: ArrayIndexEnd }) 
 
     } 
 
     else { 
 
      this.setState({ ArrayIndexStart: 24,ArrayIndexEnd: ObjectArray.length }) 
 
     } 
 
    } 
 
    render() { 
 
    return(
 
      
 
     <div> 
 
     <button onClick={() => this.handleButtonLeft(this.state.ArrayIndexStart - 8, this.state.ArrayIndexEnd - 8)}>left</button>  
 
     <button onClick={() => this.handleButtonRight(this.state.ArrayIndexStart + 8, this.state.ArrayIndexEnd + 8)}>right</button> 
 
     <div> 
 
        <p>{this.state.ArrayIndexStart}</p> 
 
        <p>{this.state.ArrayIndexEnd}</p> 
 
     </div> 
 
     </div> 
 
    ) 
 
     for(var i = this.state.ArrayIndexStart;i<this.state.ArrayIndexEnd;i++) 
 
     { 
 
      return(
 
       <div> 
 
       <p>{ObjectArray[i].letter}</p> 
 
       </div> 
 
      ) 
 
     } 
 

 

 
     
 
    }} 
 
    ReactDOM.render(
 
    <ImageViewer />, 
 
    document.getElementById('root') 
 
    )
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>
我做了这个验证码,但双倍返还型不起作用,这是不可能从这个for循环返回超过1元。 我不知道如何使它工作。

+1

无需单独'setState'呼叫,可以做的设置与同一呼叫 – nem035

+0

感谢尖。 – AESTHETICS

回答

2

所有的render()你的第一个return语句后的代码将被忽略 - 一旦功能已恢复则其停止执行。使用像ESLint这样的工具通常很有用,它可以告诉你什么时候是这种情况,并指导你编写更好的代码。

就你的情况而言,你可以用一个for循环遍历ObjectArray来创建你需要的元素,但在JSX中使用一些函数式编程技术来实现这一点要容易得多。

我已更新您的代码段以显示执行此操作的一种方法。它首先使用切片函数:

ObjectArray.slice(startIndex, endIndex) 

它返回一个只包含开始和结束索引之间元素的新数组。例如,

[1,2,3,4,5,6].slice(1, 3); // returns [2,3,4] 

一旦我们切片阵列,我们需要的部分,我们可以然后使用map函数到阵列中的每个元素转换成我们所需要的形式。

ObjectArray.map(obj => obj.letter); 

地图功能只有一个参数,其将依次施加到所述阵列的每个成员(lambda函数obj => obj.letter)。

一个简单的例子可以在阵列中每增加一倍数量:

[1,2,3,4].map(x => x * 2); // returns [2,4,6,8]; 

我也做了一些修改,以简化你的点击处理函数。它使用功能的setState说法,即

this.setState(previousState => { 
    return { 
     // state update object 
    } 
}); 

这是当你的下一个状态取决于之前的状态的值使用正确的方法 - 在你的代码中的下一个索引取决于前指数值。这也极大地简化了JSX允许你做:

onClick={this.handleButtonClick(increment)} 

对于这两个按钮,通过负增量去“左”和积极的增量去“正确的”。

var ObjectArray =[{"letter":"a"},{"letter":"b"},{"letter":"c"},{"letter":"d"},{"letter":"e"},{"letter":"f"},{"letter":"g"},{"letter":"h"},{"letter":"i"},{"letter":"j"},{"letter":"k"},{"letter":"l"},{"letter":"ł"},{"letter":"m"},{"letter":"n"},{"letter":"ń"},{"letter":"o"},{"letter":"ó"},{"letter":"p"},{"letter":"q"},{"letter":"r"},{"letter":"s"},{"letter":"ś"},{"letter":"t"},{"letter":"u"},{"letter":"v"},{"letter":"w"},{"letter":"x"},{"letter":"y"},{"letter":"z"},{"letter":"ź"},{"letter":"ż"}]; 
 

 
class ImageViewer extends React.Component { 
 
    constructor() { 
 
     super(); 
 
     this.state = { 
 
      ArrayIndexStart: 0, 
 
      ArrayIndexEnd: 8 
 
     }; 
 
     this.handleButtonClick = this.handleButtonClick.bind(this); 
 
    } 
 

 
    handleButtonClick(increment) { 
 
     this.setState(prevState => { 
 
      if (prevState.ArrayIndexStart + increment >= 8 && 
 
       prevState.ArrayIndexEnd + increment <= 
 
       ObjectArray.length) { 
 
       return { 
 
        ArrayIndexEnd: prevState.ArrayIndexEnd + increment, 
 
        ArrayIndexStart: prevState.ArrayIndexStart + increment 
 
       }; 
 
      } else if (increment < 0) { 
 
       return { 
 
        ArrayIndexEnd: 8, 
 
        ArrayIndexStart: 0 
 
       }; 
 
      } else { 
 
       return { 
 
        ArrayIndexEnd: ObjectArray.length, 
 
        ArrayIndexStart: ObjectArray.length - increment 
 
       } 
 
      } 
 
     }); 
 
    } 
 
    render() { 
 
    return(
 
      
 
     <div> 
 
     <button onClick={() => this.handleButtonClick(-8)}>left</button>  
 
     <button onClick={() => this.handleButtonClick(8)}>right</button> 
 
     <div> 
 
        <p>{this.state.ArrayIndexStart}</p> 
 
        <p>{this.state.ArrayIndexEnd}</p> 
 
     </div> 
 

 
     {ObjectArray.slice(this.state.ArrayIndexStart, this.state.ArrayIndexEnd 
 
     ).map(obj => obj.letter) 
 
     } 
 
     </div> 
 
    ) 
 

 

 
     
 
    }} 
 
    ReactDOM.render(
 
    <ImageViewer />, 
 
    document.getElementById('root') 
 
    )
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

+0

非常感谢! – AESTHETICS

+0

很高兴为您提供帮助 - 我已经编辑了一些您可能会觉得有用的其他更改。 –

1

没有返回语句结束返回的地方,所以你不能返回两次,并希望看到两者,渲染函数将在第一次返回后停止。

一个简单的.map()函数迭代并返回每个对象到你的渲染函数,这将是你的金钥匙在这里。考虑下面的代码:

render() { 
    return <div> 
     <button onClick={() => this.handleButtonLeft(this.state.ArrayIndexStart - 8, this.state.ArrayIndexEnd - 8)}>left</button>  
     <button onClick={() => this.handleButtonRight(this.state.ArrayIndexStart + 8, this.state.ArrayIndexEnd + 8)}>right</button> 
     <div> 
      <p>{this.state.ArrayIndexStart}</p> 
      <p>{this.state.ArrayIndexEnd}</p> 
     </div> 
     <div> 
      {ObjectArray.slice(this.state.ArrayIndexStart, this.state.ArrayIndexEnd).map(item => { 
       return <p>{item.letter}</p> 
      })} 
     </div> 
    </div> 
} 
+0

我不想渲染整个对象数组,但从ArrayIndexStart开始,并在ArrayIndexEnd结束。 – AESTHETICS

+0

感谢您的输入。 – AESTHETICS

+0

您可以使用.slice()然后使用.map()。 –