Кнопка React read more

#reactjs

#reactjs

Вопрос:

Я новичок в React и получаю данные из https://api.themoviedb.org/3 API.

Когда я получаю название каждого фильма, я хотел бы иметь Read More кнопку после усечения текста, но я изо всех сил пытаюсь этого добиться. Заранее спасибо.

 import React, { useState, useEffect } from 'react';
import axios from './axios';
import './Row.css'

// Append in order to retrive images
const base_url = 'https://image.tmdb.org/t/p/original/';

function Row({ title, fetchUrl, isLargeRow }) {
    const [movies, setMovies] = useState([]);

    useEffect(() => {
        async function fetchData() {
            const request = await axios.get(fetchUrl);
            setMovies(request.data.results);
            return request;
        }
        fetchData();
    }, [fetchUrl]);

    console.log(movies);

    function truncate(str, n) {
        return str?.length > n ? str.substr(0, n - 1)   '...' : str;
    }


    return (
        <div className='row'>
            <h1>{title}</h1>
            <div className='row__posters'>

                {movies.map((movie) => (
                    <div className='bic'>
                        <img
                            key={movie.id}
                            className={`row__poster ${isLargeRow amp;amp; "row__posterLarge"}`}
                            src={`${base_url}${isLargeRow ? movie.poster_path : movie.backdrop_path}`}
                            alt={movie.name}

                        />
                        <p>{movie.original_title || movie.name}</p>
                        <span>Rating: {movie.vote_average}</span>
                        <p>Polularity: {movie.popularity}</p>
                        <p className='desc'>{truncate(movie.overview, 350)}</p>

                    </div>
                ))}
            </div>
        </div>

    );
}

export default Row;
  

Комментарии:

1. пожалуйста, приходите с рабочим фрагментом, если у вас есть фрагмент, который четко показывает вашу проблему, он решит вашу проблему намного быстрее, чем без фрагмента

Ответ №1:

Сначала вы должны переместить свой отдельный фильм в другой компонент, а с помощью внутреннего состояния компонента переключить расширенную переменную, которая сообщит вам, показывать ли обзор всего фильма или усеченную часть

     import React, { useState, useEffect } from 'react';
    import axios from './axios';
    import './Row.css'

    // Append in order to retrive images
    const base_url = 'https://image.tmdb.org/t/p/original/';


    function truncate(str, n) {
        return str?.length > n ? str.substr(0, n - 1)   '...' : str;
    }

    const Movie = ({ movie }) => {
      const [expanded, setExpanded] = useState(false);

      return(
        <div className='bic'>
            <img
                key={movie.id}
                className={`row__poster ${isLargeRow amp;amp; "row__posterLarge"}`}
                src={`${base_url}${isLargeRow ? movie.poster_path : movie.backdrop_path}`}
                alt={movie.name}

            />
            <p>{movie.original_title || movie.name}</p>
            <span>Rating: {movie.vote_average}</span>
            <p>Polularity: {movie.popularity}</p>
            <p className='desc'>{expanded ? movie.overview : truncate(movie.overview, 350)}</p>
            <button onClick={() => setExpanded(!expanded)}>Read more</button>
        </div>
      )
    }

    function Row({ title, fetchUrl, isLargeRow }) {
        const [movies, setMovies] = useState([]);

        useEffect(() => {
            async function fetchData() {
                const request = await axios.get(fetchUrl);
                setMovies(request.data.results);
                return request;
            }
            fetchData();
        }, [fetchUrl]);

        console.log(movies);

        return (
            <div className='row'>
                <h1>{title}</h1>
                <div className='row__posters'>

                    {movies.map((movie) => (
                        <Movie movie={movie} />
                    ))}
                </div>
            </div>

        );
    }

    export default Row;

  

Комментарии:

1. Чао @Giovanni спасибо за ваш ответ, не уверен, что я ошибаюсь, но я получаю большую жирную ошибку, в которой говорится, что «фильмы не определены», как это.

2. Чао @FabioTorti единственное место, где я вижу переменные movies, находится внутри компонента Row, проверьте, правильно ли извлекаются ваши fetchData и передаются ли данные в setMovies, также в качестве дополнительной проверки на вашей карте сделайте это {movies amp;amp; movies.map(…)}

3. @FabioTorti Я изменил код, я забыл передать реквизит фильма в новый компонент фильма, возможно, вы получали сообщение об ошибке «фильм не определен» (не фильмы)

4. Grazie Maestro : ) теперь работает. Большое вам спасибо!!

Ответ №2:

С помощью метода JavaScript string.prototype.substring(positionA, positionB) .

 <p className='desc'>
    {movie.overview.substring(0, 350)}
    <a href="someLink">Read more ...</a>
</p>
  

Комментарии:

1. спасибо за ваш вклад, я не могу найти способ использовать ссылку перенаправления в качестве данных, поступающих из массива Api.

2. @FabioTorti Что бы вы хотели, чтобы происходило при нажатии кнопки Read more ?

3. Я хотел бы получить полное описание фильма, которое сейчас сокращено до 150 символов. По сути, я отрисовал кучу данных из Api и movie.overview — это фактически описание фильма, которое я обрезал, поэтому, когда пользователь нажимает «Подробнее», он должен получить полное описание. Спасибо

4. @FabioTorti Я бы предложил переключать класс css при нажатии read more, который скрывается с помощью read more / показывает дополнительный текст. Вы знаете, как это сделать?

5. Спасибо @koder613 решение, предоставленное giovanni, теперь работает 🙂 большое спасибо за вашу помощь 🙂