Reusing Properties Within Map Loop In ReactJS - Best Practice
I am trying to figure out the best way to render two blocks of code in ReactJS, one will be used for desktop and the other for mobile. Functionality wise they will do exactly the same thing but have different markup wrapped around them, an example would be a carousel that renders differently on mobile.
I am using the map function to iterate over the object properties, I have working code below but I am duplicating variables and reassigning the same values which is obviously inefficient as I am doing this for each code block.
Can anyone suggest a nice / best practice way of doing what I need?
Sorry for the basic question!
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>
)}
Answer
Updated answer:
If the inner items can have different markup, I would say it depends how different their markup is going to be. For example, you could have two separate methods that prepare the markup of the mobile and non-mobile version of the items separately. Something like this:
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>
)
}
You could also have a single method if the differences between mobile and non-mobile are not too big. For example, using ES6 arrow functions:
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>
)
}
Original answer below:
If I understood correctly and the inner items have the same markup, you could extract the function passed into map
to a separate method:
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>
)
}
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM