My react render slowly works in mobile.
My component renders list of some items. This is the render method.
return (
<div className={ bemCn('columns-container') }>
{ isLanding && isMobileMode && this.renderTabs(platform) }
<div className={ bemCn('columns', {isLanding: isLanding}) }>
<div className={ bemCn('column').mix(bemCn('counters', {isLanding: isLanding, isMobileModeAndLanding: isMobileMode && isLanding})) }>
{this.props.table.rows.map(row => (
<div className={ bemCn('counters-item') } key={ row }>
{this.props.from + row}
</div>
))}
</div>
{columnsCategory[platform].map(column => (
<div key={ column } className={ bemCn('column', {isLanding: isLanding}) }>
<div className={ bemCn('title', { [column]: true, isLanding: isLanding }) }>{TITLES[column]}</div>
<ul className={ bemCn('list') }>
{this.props.table.rows.map(idx => {
const item = columns[column]
? columns[column].find(item => item.position === idx + 1)
: null
if (!item) {
return <li key={ idx } className={ bemCn('list-item', { empty: true, isLandingAndEmpty: isLanding }) } />
}
if (!applications[item.app_id]) return null
let modifier
let prefix
let positionChangeValue
const yesterdayPosition = yesterday[`${item.app_id}:${column}`]
if (yesterdayPosition) {
modifier = item.position < yesterdayPosition ? 'up' : 'down'
prefix = item.position < yesterdayPosition ? '+' : '-'
positionChangeValue = Math.abs(item.position - yesterdayPosition)
}
const isBlur = chartsTypeFilterSet.size ? this.checkBlur(item.app_id, publishers, advertisers, chartsTypeFilterSet) : false
return (
<li key={ idx } className={ bemCn('list-item', { blur: isBlur, isLanding: isLanding })() }>
<Link className={ bemCn('link', {isLanding: isLanding}) } to={ this.getLink(item.app_id, applications[item.app_id].slug) }>
{isLanding && <div className={bemCn('mobile-counter', {isMobileMode: isMobileMode})}>{ idx + 1 }</div>}
<div className={ bemCn('icon') }>
<img
src={ setImageSize({
url: applications[item.app_id].icon_url,
platform,
size: 44
}) }
alt={ applications[item.app_id].name }
/>
</div>
<div className={ bemCn('info', {isLanding: isLanding}) }>
<div className={ bemCn('info-names') }>
<div className={ bemCn('publisher').mix('u-text-ellipsis') }>
{applications[item.app_id].developer.name}
</div>
<div className={ bemCn('name').mix('u-text-ellipsis') }>
{applications[item.app_id].name}
</div>
</div>
<div className={ bemCn('rating') }>
{!!item.rating && <StarRatings rating={ item.rating } starDimension="12px" starSpacing="1px" />}
{publishers[item.app_id] && (
<SimpleTip tip="Advertising monetization of this app" noWrap>
<div className={ bemCn('pub-icon')() }>Pub</div>
</SimpleTip>
)}
{advertisers[item.app_id] && (
<SimpleTip tip="Advertising campaigns of this app" noWrap>
<div className={ bemCn('pub-icon', { ad: true })() }>Ad</div>
</SimpleTip>
)}
{!isLanding && fb[item.app_id] && (
<SimpleTip tip="fb" noWrap>
<div className={ bemCn('pub-icon', { fb: true })() }>Fb</div>
</SimpleTip>
)}
</div>
</div>
<div className={ bemCn('changes') }>
<div className={ bemCn('price') }>
{item.price === 'FREE' || item.code === 'FREE' ? 'FREE' : null}
{item.price !== 0 && (
<span>
{item.code} {item.price}
</span>
)}
</div>
{positionChangeValue !== 0 && (
<div className={ bemCn('changes-value', { [modifier]: true }) }>
{prefix}
{positionChangeValue}
</div>
)}
</div>
</Link>
</li>
)
})}
</ul>
</div>
))}
</div>
</div>
)
}
I don't know why render so slow. In this render I often use construction className={ bemCn('info', {isLanding: isLanding}) } (check isLanding). How does this construction affect performance, if I need render >100 items?
Related
I have a calendar that i'm trying set a reminder to a specific day.
This day i set in a form but i don't know how to set reminder for a day on calendar.
{calendar.map((week, index) =>
<div key={index} className="week">
{week.map((day, index) =>
<>
<div key={index} className="day " onClick={() => !beforeToday(day) && setValue(day) || setIsOpenModal(true)}>
<div className={dayStyles(day, value)}>
{day.format('D').toString()}
<div className='reminder'>
{formData.map(item => getDay === item.Date ? (
<>
<p>{item.Reminder}</p>
<p>{item.Date}</p>
<p>{item.Time}</p>
<p>{item.City}</p>
</>
) : (
''
))}
</div>
</div>
</div>
</>
)}
</div>
)}
The problem is undefined of currentPackage.
render() {
const {
hasAccounts,
asideClassesFromConfig,
disableScroll,
htmlClassService,
currentPackage,
user,
} = this.props;
const isActive = checkStatus(user?.status);
const packageLogo = currentPackage.name && currentPackage.logo && (
<div className="vk-inductee-button-wrapper">
<div className="vk-inductee-button-image-wrapper">
<img
src={currentPackage.logo}
className="vk-inductee-button-image"
alt="inductee-img"
/>
</div>
<div className="vk-inductee-button-label">
<span>{currentPackage.name}</span>
</div>
</div>
);
return (
<>
<button className="kt-aside-close" id="kt_aside_close_btn">
<i className="la la-close" />
</button>
<div
id="kt_aside"
ref={this.asideOffCanvasRef}
className={`kt-aside ${asideClassesFromConfig} kt-grid__item kt-grid kt-grid--desktop kt-grid--hor-desktop`}>
<Brand />
<div
id="kt_aside_menu_wrapper"
className="kt-aside-menu-wrapper kt-grid__item kt-grid__item--fluid">
<AsideDropdown />
{isActive ? (
<Link to="/shop/my-packages">{packageLogo}</Link>
) : (
packageLogo
)}
{disableScroll && <Menu htmlClassService={htmlClassService} />}
{!disableScroll && (
<PerfectScrollbar
options={{ wheelSpeed: 2, wheelPropagation: false }}>
<Menu htmlClassService={htmlClassService} />
</PerfectScrollbar>
)}
{hasAccounts && <AsideFooter />}
</div>
</div>
</>
);
}
}
you might do something like
const packageLogo = currentPackage && currentPackage.name && currentPackage.logo && (
<>
//your code
</>
)
the problem is that currentPackage is undefined, but you're checking if currentPackage.name is truthy. Since the property name doesn't exist on undefined, you get that error. You should just need to check that currentPackage itself is truthy before checking specific properties on it.
I am trying to achieve the following for a special page
const Pricing = () => {
return (
<main class="o-main">
<section class="plan">
<div class="plan">
<div class="plan">
<h1 class="plan">Select the best plan</h1>
<p class="plan">from plan1 to plan3</p>
</div>
</div>
</section>
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan1</p>
</div>
</div>
{isLoggedin() ? (
{userPlan() === 'plan1' ? (
<FaCheckCircle />
<a class="plan">current plan</a>
) : (
<a class="plan" onClick={() => {...}}>sign up</a>
)}
) : (
sign up
)}
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan2</p>
</div>
</div>
{isLoggedin() ? (
<>
{userPlan() === 'plan2' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>upgrade to plan2</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
<div class="plan">
<div class="plan">
<h1 class="plan">features</h1>
<p class="plan">features of plan3</p>
</div>
</div>
{isLoggedin() ? (
<>
{userPlan() === 'plan3' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>upgrade to plan3</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
</main>
);
};
export default Pricing;
userPlan() is a function of fetch API call that returns a string like plan1 or plan2
but i am getting the following error
Syntax error: Unexpected token
{userPlan() === 'plan1' ? (
^
anything am missing or the logic is not possible in react?
before using this function's return value , check if it is available:
isLoggedin() && userPlan() ? ...
issue was that here is what is what i really had
{isLoggedin() ? (
{userPlan() === 'plan1' ? (
<FaCheckCircle />
<a class="plan">current plan</a>
) : (
<a class="plan" onClick={() => {...}}>sign up</a>
)}
) : (
sign up
)}
and here is what worked and removed the syntax error
{isLoggedin() ? (
<>
{userPlan() === 'plan1' ? (
<>
<FaCheckCircle />
<a class="plan">current plan</a>
</>
) : (
<>
<a class="plan" onClick={() => {...}}>sign up</a>
</>
)}
</>
) : (
<>
sign up
</>
)}
the thing is sometimes it does not complain about the <> and </> and sometimes it does, in this case
anyone that knows why this is inconsistent, please comment below
I have this array of rows that I try to sort alphabetically with the sortByTitle() function. The sort method I am pretty sure is OK but there must be something with where I am calling it that makes it not work and it does not mutate the array at all. It may be because of the lifecycle of react.
The sort on getRows() works perfectly.
getHistory() {
if (this.state.historyUser && this.state.historyUser.length) {
return this.state.historyUser.map(x => {
x.state = x.finishDate ? 'closed' : 'open';
return x;
});
} else {
return [];
}
}
getRows() {
let rows = this.state.rows || this.getHistory();
rows.sort((a, b) => b.creationDate - a.creationDate)
return rows.map((x, j) => {
return (
<div key={j} className={`testTable__row testTable__test testTable__test--${x.state}`}>
{this.allTypes.map((type, i) => {
let value = type.className !== 'checks' ? x[type.prop] : x.checked;
if (type.className === 'name') {
value = (
<a href={`/test/${x._id}#1`}>{x[type.prop]}</a>
);
}
return (
<CellUser
key={i}
id={x._id}
value={value}
className={type.className}
changeChecked={this.changeChecked}
isSimulacro={x.isSimulacro}
score={x.scoreProMIR}
/>
);
})}
</div>
);
});
}
handleInputChange(e) {
let rows = this.state.historyUser;
const selector = e.target.getAttribute("label")
rows = rows.filter(elm => elm[selector].toLowerCase().includes(e.target.value.toLowerCase()));
this.setState({ inputValue: e.target.value, rows: rows});
}
sortByTitle() {
let rows = this.state.rows || this.getHistory();
rows.sort((a, b) => a.title.localeCompare(b.title));
this.setState({ rows: row });
}
render() {
return (
<div style={{ height: '100%', width: '100%' }}>
<div className="testTable">
<div className="testTable__row testTable__header">
<div className="testTable__column testTable__column--name">
Nombre
<input type="text" label="title" onChange={this.handleInputChange} />
<button onClick={this.sortByTitle}> Ordenar </button>
</div>
<div className="testTable__column testTable__column--score"> Nota </div>
<div className="testTable__column testTable__column--type"> Tipo </div>
<div className="testTable__column testTable__column--date"> Fecha </div>
<div className="testTable__column testTable__column--state"> Estado </div>
<div className="testTable__column testTable__column--checks">
<label>
Abiertos <Checkbox selected={this.state.checkOpen} onClick={this.allOpened} />
</label>
<label>
Cerrados <Checkbox selected={this.state.checkClose} onClick={this.allClosed} />
</label>
<label>
Todos <Checkbox selected={this.state.selectedAllRows} onClick={this.allRows} />
</label>
</div>
</div>
<div className="testTable__body">
<Scrollbars {...scrollbarsProps()}>{this.getRows()}</Scrollbars>
</div>
<div
className={`testTable__row testTable__footer${
this.state.btnClose || this.state.btnReset || this.state.btnReopen ? ' active' : ''
}`}
>
<ReactCSSTransitionGroup
component="div"
transitionName="topBottom"
transitionEnterTimeout={0}
transitionLeaveTimeout={0}
>
{this.state.btnClose ? (
<button className="button button--close" onClick={this.requestAction} name="close">
Cerrar seleccionados
</button>
) : null}
{this.state.btnReset ? (
<button className="button button--reset" onClick={this.requestAction} name="reset">
Resetear seleccionados
</button>
) : null}
{this.state.btnReopen ? (
<button className="button button--open" onClick={this.requestAction} name="open">
Reabrir seleccionados
</button>
) : null}
{this.state.btnAddToStats ? (
<button className="button button--add" onClick={this.requestAction} name="add">
Añadir a estadísticas
</button>
) : null}
</ReactCSSTransitionGroup>
</div>
</div>
<ReactCSSTransitionGroup
component="div"
transitionName="topBottom"
className={`superCoverMsg${this.state.confirmAction ? '' : ' none'}`}
transitionEnterTimeout={0}
transitionLeaveTimeout={0}
>
{this.state.confirmAction ? (
<div className="coverMsg confirmPopUp" key="0">
<p>{this.state.textAction}</p>
<div className="coverLabelInput coverLabelInput__botones columnWidth">
<ul className="cien">
<li className="cincuenta cancelar">
<a onClick={this.removeConfirmAction} href="#" title="Cancelar">
Cancelar
</a>
</li>
<li className="cincuenta aceptar">
<a onClick={this.aceptAction} href="#" title="Aceptar">
Aceptar
</a>
</li>
</ul>
</div>
</div>
) : null}
</ReactCSSTransitionGroup>
</div>
);
}
}
It looks like your setting rows equal to row, which I don't see defined. Maybe change this
this.setState({ rows: row });
to
this.setState({ rows: rows });
Also I think the react-friendly way to modify an array from state would be use a spread operator so as not to mutate the state object directly, like so:
let rows = [...this.state.rows] || this.getHistory();
sortByTitle() {
let rows = this.state.rows || this.getHistory();
rows.sort((a, b) => a.title.localeCompare(b.title));
this.setState({ rows: row });
}
You are mutating the state. instead copy the content into separate new array, sort it and use that new variable in .setState.
I'm using map in react to show a feed of facebook posts, but i don't want the post to render if the message field is missing from the json data.
If I do this I get an error ('if' is an unexpected token) and my project won't build
return (
<Slider
{...Settings}>
{postsAvailable && posts.map((post, index) => (
if (!post.message) return null
return (<div key={post.id}>
{ index === 0 && <Item /> }
{ index > 0 && <div className='item'>
<img data-original={post.full_picture} className='img-responsive' />
<div className={`facebook-content slide-${post.id}`}>
<p className='text'>{post.message}</p>
</div>
</div> }
</div>)
))}
</Slider>
)
You can use filter first:
posts.filter((post) => post.message).map((post, index) => (...
Although, if possible you should filter when you get the posts, and not in the render function. Do as little as possible in the render function - for a good overview, and for performance.
You are not giving your function given to map a body. Change () to {} and it will work as expected.
return (
<Slider {...Settings}>
{postsAvailable &&
posts.map((post, index) => {
if (!post.message) return null;
return (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
);
})}
</Slider>
);
Alternatively you could filter out all the posts that don't have a message first and then map those that does.
return (
<Slider {...Settings}>
{postsAvailable &&
posts
.filter(post => post.message)
.map((post, index) => (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
))}
</Slider>
);