简体   繁体   中英

I am trying to align movieCards side by side. But they are aligning in a column

This is my movie list component. I tried different attributes in the div section to get the cards in a row. But all the cards are aligned in a column.should i use either flex or grid.If yes how can i use them. Even i referred to many resources for this.But didn't worked for me. What should I do to get the cards as I wish . Please assist me.

import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import MovieCard from './MovieCard'

const MoviesList = (props) => {
    const [search, setSearch] = useState('')
    const [filterBy, setFilterBy] = useState([])
    const [orderBy, setOrderBy] = useState('')

    const movies = useSelector((state) => {
        console.log(state.movies)
        return state.movies
    })

    const handleChange = (e) => {
        const inputValue = e.target.value
        setSearch(inputValue)

        const filteredValue = movies.filter((movie) => {
            return movie.Title.toLowerCase().includes(inputValue)
        })
        setFilterBy(filteredValue)

        console.log(filteredValue)

    }

    const handleSelectChange = (e) => {
        setOrderBy(e.target.value)
    }

    const show = (movies) => {
        switch (orderBy) {
            case 'a-z': return [...movies.sort((a, b) => a.Title.localeCompare(b.Title))]
            case 'z-a': return [...movies.sort((a, b) => b.Title.localeCompare(a.Title))]
            case '1-100': return [...movies.sort((a, b) => a.imdbRating - b.imdbRating)]
            case '100-1': return [...movies.sort((a, b) => b.imdbRating - a.imdbRating)]
            default: return [...movies]

        }
    }



    return (
        <div className='container'>
            <div className='d-flex mb-3 '>
                <h1 style={{ textAlign: 'center', border: 'solid lightgreen', backgroundColor: 'white' }} >My Movie List</h1>
                <form style={{ float: 'right', marginRight: '35px' }}>
                    <input type="text" placeholder='search by name' value={search} onChange={handleChange} />
                    <select value={orderBy} onChange={handleSelectChange} >
                        <option value="">orderBy</option>
                        <option value="a-z">a-z</option>
                        <option value="z-a">z-a</option>
                        <option value="1-100">1-100</option>
                        <option value="100-1">100-1</option>
                    </select>
                </form>
            </div>
            <div className=" row pt-2  justify-content-around " style={{ textAlign: 'center', width: '100%' }}>

                {
                    filterBy.length > 0 ? (
                        filterBy.map((movie) => {
                            return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
                        })
                    ) : (
                        show(movies).map((movie) => {
                            return <MovieCard key={movie.imdbID} {...movie} />
                        })
                    )
                }
            </div>

        </div >
    )
}

export default MoviesList

And this is Movie card component

import React from 'react'
import { useDispatch } from 'react-redux'
import { removeMovie } from '../actions/moviesAction'


const MovieCard = (props) => {
    console.log(props)
    const { Title, Poster, imdbRating, imdbID } = props
    const dispatch = useDispatch()

    return (
        <div className="card mt-2 p-2 bd-highlight border shadow rounded" style={{ width: '16rem' }}>
            <img className="card-img-left pt-2" src={Poster} alt={Title} style={{ width: '200px', height: '200px' }} />
            <div className="card-body">
                <h4 className="card-title">Name : {Title}</h4>
                <h5 className="card-title">Ranking : #{imdbRating}</h5>
                <ion-icon name="trash" style={{ color: 'red' }} onClick={() => {
                    dispatch(removeMovie(imdbID))
                }}>
                </ion-icon>
            </div>
        </div>
)}
export default MovieCard

Please help me to resolve this. Thankyou

Try providing display: flex , to the div rendering MovieCard , like this:

 <div className=" row pt-2  justify-content-around "
     style={{ textAlign: 'center', width: '100%', display: 'flex' }}>
            {
                filterBy.length > 0 ? (
                    filterBy.map((movie) => {
                        return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
                    })
                ) : (
                    show(movies).map((movie) => {
                        return <MovieCard key={movie.imdbID} {...movie} />
                    })
                )
            }
 </div>

You can just use flex here.

add the below code to your parent div (div containing all the cards).

If you have a css file add a class to that div and add the following styles.

display: flex;
flex-wrap: wrap;
justify-content: center;

or if you want to use inline styling do the following:

<div className=" row pt-2  justify-content-around " style={{ textAlign: 'center', width: '100%', display: "flex", flexWrap: "wrap", justifyContent: "center"  }}>
{filterBy.length > 0 ? (
         filterBy.map((movie) => {
             return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
          })
     ) : (
         show(movies).map((movie) => {
             return <MovieCard key={movie.imdbID} {...movie} />
         }
     )
)}
</div>

Try using a grid method something like the code below will allow you control the number of rows and columns you want as well as size them.

**

 <h1>Example { grid-template-rows: 40% 50% 50px;}</h1> <p><strong style="color: red">The shorthand property, grid-template, can replace both </strong>grid-template-rows and grid-template-columns.</p> <hr> <p style="font-family: Courier">When using grid-template, the values before the slash will determine the size of each row. The values after the slash determine the size of each column. </p><hr> <p style="font-family: Courier">In this example there are 3 rows and 3 columns added to the grid.</p><h1>Example {grid-template: 40% 50% 50px/100px 50% 200px;}</h1><br> <p><strong style="color: red">By using the (fr) unit, we can define the size of columns and rows as a fraction of the grid's length and width.</strong><br>Using (fr) makes it easier to prevent grid items from overflowing the boundaries of the grid.</p> <h1>Example {grid-template: 1fr 1fr 1fr / 3fr 50% 1fr;}<br> width: 400px;<br>

**

If you're using Bootstrap then you don't need to use flex nor grid directly. This is the Bootstrap's way to achieve the desired layout:

 <div className="row"> {movies.map(item => ( <div className="col"> // then here yo can put your card for the movie </div> ))} </div>

This is the Bootstrap doc about it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM