循环使用React中的某些元素

时间:2017-08-06 23:14:09

标签: javascript reactjs

我试图遍历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')
    )
&#13;
<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>
&#13;
&#13;
&#13; 我做了这个代码,但双返回类型不起作用,并且不能从这个for循环返回多于1个元素。 我不知道如何让它发挥作用。

2 个答案:

答案 0 :(得分:2)

来自render()的第一个return语句之后的所有代码都被忽略 - 一旦函数返回,它的执行就会停止。使用像ESLint这样的工具通常很有用,它可以告诉你何时是这种情况并指导你编写更好的代码。

在你的情况下,你可以使用for循环遍历ObjectArray来创建你需要的元素,但是在JSX中使用一些函数式编程技术更容易。

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

ObjectArray.slice(startIndex, endIndex)

返回一个新数组,该数组仅包含start和end索引之间的元素。例如,

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

一旦我们切割了我们需要的数组部分,我们就可以使用map函数将数组的每个元素转换为我们需要的形式。

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

map函数接受一个参数(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)}

对于这两个按钮,将负增量传递给&#34; left&#34;一个积极的增量去&#34;对&#34;。

&#13;
&#13;
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')
    )
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分: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>
}