在ReactJS中重用映射循环中的属性-最佳实践

Reusing properties within map loop in ReactJS - best practice

本文关键字:属性 最佳 循环 ReactJS 映射      更新时间:2023-09-26

我正在努力找出在ReactJS中呈现两个代码块的最佳方法,一个用于桌面,另一个用于移动。就功能而言,它们会做完全相同的事情,但周围有不同的标记,例如在移动设备上呈现不同的旋转木马。

我正在使用map函数迭代对象属性,下面有工作代码,但我正在复制变量并重新分配相同的值,这显然是低效的,因为我对每个代码块都这样做。

有人能提出一个很好的/最佳实践的方式来做我需要的事情吗?

很抱歉出现了基本问题!

render: function() {
return (
    <div>
        <div className="hidden-xs">
            {
                this.state.userItems.map(function (item) {
                    var someValue = 'value' in item ? item.value : '';
                    var anotherValue = 'anotherValue' in item ? item.anotherValue : '';
                    return (
                        <div key={someValue}>
                            {someValue}<br>{anotherValue}
                        </div>
                    )
                })
            }
        </div>
        <div className="visible-xs">
            {
                this.state.userItems.map(function (item) {
                    var someValue = 'value' in item ? item.value : '';
                    var anotherValue = 'anotherValue' in item ? item.anotherValue : '';
                    return (
                        <div key={someValue}>
                            <div className="differentMarkup">
                              {someValue}<br>{anotherValue}
                            </div>
                        </div>
                    )
                })
            }
        </div>
    </div>
)}

更新答案:

如果内部项可以有不同的标记,我想说这取决于它们的标记的不同程度。例如,你可以有两个单独的方法,分别准备移动和非移动版本的项的标记。类似这样的东西:

renderUserItem: function(itemData) {
    return (
        <div key={itemData.someValue}>
            {itemData.someValue}<br>{itemData.anotherValue}
        </div>
    )
},
renderMobileUserItem: function(itemData) {
    return (
        <div key={itemData.someValue}>
            <div className="differentMarkup">
                {itemData.someValue}<br>{itemData.anotherValue}
            </div>
        </div>
    )
},
prepareItemData: function(item) {
    return {
        someValue: item.value ? item.value : '';
        anotherValue: item.anotherValue ? item.anotherValue : '';
    };
},
render: function() {
    // Prepare the variables you will need only once
    let parsedUserItems = this.state.userItems.map(this.prepareItemData);
    return (
        <div>
            <div className="hidden-xs">
                { parsedUserItems.map(this.renderUserItem) }
            </div>
            <div className="visible-xs">
                { parsedUserItems.map(this.renderMobileUserItem) }
            </div>
        </div>
    )
}

如果移动和非移动之间的差异不是太大,你也可以有一个单一的方法。例如,使用ES6箭头功能:

renderUserItem: function(itemData, renderWrapper) {
    return (
        <div key={itemData.someValue}>
            {renderWrapper ? <div className="differentMarkup"> : ''}
                {itemData.someValue}<br>{itemData.anotherValue}
            {renderWrapper ? </div> : ''}
        </div>
    )
},
render: function() {
    // Prepare the variables you will need only once
    let parsedUserItems = this.state.userItems.map(this.prepareItemData);
    return (
        <div>
            <div className="hidden-xs">
                { parsedUserItems.map(item => this.renderUserItem(item, false)) }
            </div>
            <div className="visible-xs">
                { parsedUserItems.map(item => this.renderUserItem(item, true)) }
            </div>
        </div>
    )
}



下面的原始答案:

如果我理解正确,并且内部项具有相同的标记,那么可以将传递到map中的函数提取到一个单独的方法:

renderUserItem: function(item) {
    var someValue = 'value' in item ? item.value : '';
    var anotherValue = 'anotherValue' in item ? item.anotherValue : '';
    return (
        <div key={someValue}>
            {someValue}<br>{anotherValue}
        </div>
    )
},
render: function() {
    return (
        <div>
            <div className="hidden-xs">
                { this.state.userItems.map(this.renderUserItem) }
            </div>
            <div className="visible-xs">
                { this.state.userItems.map(this.renderUserItem) }
            </div>
        </div>
    )
}