Hice una cuadrícula de este tipo usando grid antd . código aquí .
const { Row, Col } = antd;
const App = () => (
<Row>
<Col className={'first'} span={16}>
<img src="https://picsum.photos/800/400?random=1"/>
</Col>
<Col span={8}>
<Row>
<Col className={'second'} span={24}>
<img src="https://picsum.photos/800/400?random=2"/>
</Col>
<Col className={'third'} span={24}>
<img src="https://picsum.photos/800/400?random=3"/>
</Col>
</Row>
</Col>
</Row>
)
const ComponentDemo = App;
ReactDOM.render(<ComponentDemo />, mountNode);
Estoy recibiendo datos del servidor. Puede haber más de 3 de ellos allí. Debería generar los primeros 3 así. El resto se mostrará después de presionar el botón. ¿Cómo se puede lograr este efecto en myData.map() . ¿Para generar estos elementos sin usar índices?
intentare hacer algo como esto
dataSale.slice(0,maxCount).map(({...item},index)=>(
(index===0)?(
<Col key = {index} span={16}>
<SaleCard {...item}/>
</Col>
):(
<Col key={index} span={8}>
<SaleCard {...item}/>
</Col>
)
))
Espero que esto ayude. El siguiente código debería funcionar con cualquier número de enlaces de imágenes enviados por el servidor. Me he burlado con 9 imágenes.
Seguí el enfoque de componentes, como lo que se supone que debes hacer cuando trabajas con React. Creé algunos componentes y los volví a juntar para crear el diseño que querías con map() .
const { Row, Col, Button } = antd;
const {useState} = React;
const data = [
"https://picsum.photos/800/400?random=1",
"https://picsum.photos/800/400?random=2",
"https://picsum.photos/800/400?random=3",
"https://picsum.photos/800/400?random=4",
"https://picsum.photos/800/400?random=5",
"https://picsum.photos/800/400?random=6",
"https://picsum.photos/800/400?random=7",
"https://picsum.photos/800/400?random=8",
"https://picsum.photos/800/400?random=9",
]
const ColWithImage = (props) => (
<Col span={props.n % 3 == 1 ? 16 : 24}>
<img src={data[props.n-1]}/>
</Col>
)
const MainRow = (props) => {
const k = props.n*3 + 1;
return (
<Row>
<ColWithImage n={k}/>
<Col span={8}>
<Row>
<ColWithImage n={k+1}/>
<ColWithImage n={k+2}/>
</Row>
</Col>
</Row>
)}
const Container = (props) => {
// Create an iterable array depending upon the number of image links
const arr = Array.from(Array(Math.floor(data.length/3)))
// Show only one row if the button is not clicked
// But show all the rows if the button is clicked
return !props.buttonClicked
? <><MainRow n={0}/></>
: (<>
{
arr.map((item, index) => <MainRow key={index} n={index}/>)
}
</>)
}
const App = () => {
const [buttonClicked, setButtonClicked] = useState(false);
const [buttonText, setButtonText ] = useState("Show More");
const handleClick = () => {
setButtonClicked(!buttonClicked);
setButtonText(buttonClicked ? "Show More" : "Show Less");
}
return (<>
<Container buttonClicked={buttonClicked}/>
<Button onClick={handleClick}>{buttonText}</Button>
</>)
}
const ComponentDemo = App;
ReactDOM.render(<ComponentDemo />, mountNode);
Puedes ver el resultado aquí .
Creé un componente SalesView y representará el diseño según sus requisitos. Recibe una matriz de elementos de longitud menor o igual a 3 (suponga que tiene un total de 5 registros, solo se mostrarán dos registros en la segunda fila).
Espero que esta solución resuelva tu problema.
import { useState } from "react";
import { Row, Col, Button } from "antd";
import "antd/dist/antd.min.css";
const list = Array.from({ length: 20 }).map((_, i) => ({
id: i,
url: `https://picsum.photos/800/400?random=${i + 1}`,
}));
const SalesCard = ({ id, url }) => {
return <img src={url} />;
};
const SalesView = ({ items }) => {
return (
<Row>
{items?.[0] && (
<Col span={16}>
<SalesCard {...items[0]} />
</Col>
)}
{items.length > 2 && (
<Col span={8}>
<Row>
{items?.[1] && (
<Col span={24}>
<SalesCard {...items[1]} />
</Col>
)}
{items?.[2] && (
<Col span={24}>
<SalesCard {...items[2]} />
</Col>
)}
</Row>
</Col>
)}
</Row>
);
};
function App() {
const [showAll, setShowAll] = useState(false);
const totalChunks = Math.ceil(list.length / 3);
const data = Array.from({ length: showAll ? totalChunks : 1 }).map((_, index) => {
const startIndex = index * 3;
const endIndex = startIndex + 3;
return <SalesView key={index} items={list.slice(startIndex, endIndex)} />;
});
const onClick = () => setShowAll(true);
return (
<>
{data}
{!showAll && <Button onClick={onClick}>Show More</Button>}
</>
);
}
export default App;
puedes lograrlo a través de CSS o usar ternario
dataSale.map((item, index) =>
<Col key={index} span={index < 3 ? 16 : 8}>
<SaleCard {...item}/>
</Col>
)