I'm having trouble with the responsiveness of rendered items from an array of objects that are loaded by clicking a 'Load More' button. On every click 3 extra items are visible. So far so good. But when the screen-width gets smaller I want to render only two items per click and in the end only one item. The problem is that media queries, css-grid or flex-box and the load functionality presets, in the component, cancel each other out. If I want two items rendered I have to adjust the CSS rules and the actual JS code presets like the posts-per-page. In other words how to create a responsive 'Load More' functionality in react (hooks).
The component
const [ soldProperties, setSoldProperties ] = useState([])
const [ loadBtn, setLoadBtn ] = useState('Show More')
const [ currentSlice, setCurrentSlice ] = useState(3)
const [ perPage, setPerPage ] = useState(3)
useEffect(()=> {
setSoldProperties(soldProps.slice(0, currentSlice))
}, [currentSlice, soldProperties.length])
const loadMore = () => {
setCurrentSlice(currentSlice + perPage)
if (soldProperties.length === 6) {
setLoadBtn('Show Less')
}
if (soldProperties.length === soldProps.length){
setCurrentSlice(currentSlice - 6)
setLoadBtn('Show More')
}
}
return (
<div className="soldprops">
<div className="soldprops_header">Sold Properties:</div>
<div className="soldprops_grid">
{soldProperties && soldProperties.map(property => {
const { img, name, price, id } = property
return <div className="soldprops_grid_imageBox" key={id}>
<div className="image"><img src={process.env.PUBLIC_URL + `/soldProps/${img}`} alt="" style={{ width: '100%', height: 'auto' }} /></div>
<div className="footer"><span className="soldChateau">{name}</span><span className="soldPrice">${price},-</span></div>
</div>
})}
</div>
<button type="button" className="loadmoreBtn" onClick={loadMore} >{loadBtn}</button>
</div>
)
}
The scss
.soldprops {
position: relative;
max-width: 1920px;
margin: 0 auto;
height: auto;
@include center-content-column;
&_header {
width: 100%;
height: 50px;
color:rgb(163, 149, 184);
padding: 0 20px;
font-size: 1.2rem;
font-family: Arial, Helvetica, sans-serif;
@include center-content-row-start;
}
&_grid {
width: 100%;
padding: 0 20px;
margin-bottom: 50px;
height: auto;
@include center-content-row;
flex-wrap: wrap;
gap: 15px;
// display: grid;
// grid-template-columns: repeat(3, 1fr);
// grid-template-rows: repeat(1, 1fr);
// gap: 20px;
&_imageBox {
position: relative;
width:32%;
height: auto;
line-height: 0;
box-shadow: 0px 4px 4px rgb(11, 9, 14);
.image {
width: 100%;
height: auto;
opacity: 1;
}
}
}