Я не могу запустить эффект использования из запроса, когда я использую history.GoBack()

#reactjs #search #browser-history

Вопрос:

Я изучаю react и MaterialUI, и приложение, которое я создаю, посвящено поиску в api amdb и предоставлению некоторых данных.

В моем «компоненте поиска» я настроил его так, что, когда пользователь что-то автоматически пишет, он записывает запрос и запускает эффект использования с этим запросом.

Первый поиск работает идеально, я перечисляю все результаты, и вы можете перейти к нужному вам фильму. Это приведет вас к другому компоненту, renderMovie, и у него есть кнопка на предыдущую страницу (я настроил ее с помощью history.GoBack() )

Проблема появляется, когда я возвращаюсь; Я возвращаюсь к компоненту поиска, но я теряю поиск, который выполнял перед входом. У меня есть запрос по URL-адресу, но я не могу запустить эффект использования.

Я попытался изменить зависимости в эффекте, но, похоже, ничего не работает. Я тоже пытался использовать useMemo, но я не могу заставить его работать, потому что у меня нет самой функции (я имею в виду, что единственная функция, которая у меня есть, — это handleInputChange).

Не могли бы вы дать несколько советов? Как я мог это сделать? Какой подход я мог бы использовать? Или, может быть, вы могли бы дать мне другие идеи, чтобы попробовать?

Заранее спасибо!

Это мой личный компонент, если у вас есть какие-то вопросы…

 
    import React, { useEffect, useState } from 'react';
    import { useHistory, useLocation } from "react-router-dom";
    import { makeStyles } from '@material-ui/core/styles';
    import TextField from '@material-ui/core/TextField';
    import { Container, Grid } from '@material-ui/core';
    import queryString from "query-string";
    
    
    import MovieCardItem from '../components/MovieCardItem';
    import PaginationComp from '../components/PaginationComp';
    import { ReactComponent as Logo } from "../assets/Search.svg";
    import { API_KEY, URL_API } from '../utils/constants';
    
    
    const useStyles = makeStyles((theme) => ({
        root: {
            'amp; > *': {
                margin: theme.spacing(1),
                width: '25ch',
            },
        },
        bigContainer: {
            margin: '1rem auto 3rem auto',
            textAlign: 'center',
            justifyContent: 'center',
        },
        media: {
            width: '100%',
            height: '100%',
            margin: '1rem auto',
        },
        textField:{
            width: '100%'
        },
        noResults: {
            margin: '0 auto',
        }
    }));
    
    
    export default function SearchPage() {
        const classes = useStyles();
        const history = useHistory();
        const location = useLocation();
    
        const [firstRender, setFirstRender] = useState(true);
    
        const [movieList, setMovieList] = useState([]);
        const [showMovieList, setShowMovieList] = useState(false);
        const [showNoResult, setShowNoResult] = useState(false)
    
        const [page, setPage] = useState(1);
        const [pageTotal, setPageTotal] = useState(1);
        const [showPagination, setShowPagination] = useState(false);
        
    
        const handleInputChange = (e) => {
            setFirstRender(false);
            if (e.target.value === ' ') {
                e.target.value = '';  
                return null
            }
            const urlParams = queryString.parse(location.search);
            urlParams.s = e.target.value; 
            if(e.target.value === '') {
                setShowPagination(false);
                setFirstRender(true)
                history.push(`/buscar`)    
                setShowMovieList(false);
            } else {
                history.push(`?${queryString.stringify(urlParams)}`);
                setShowMovieList(true);
                setShowPagination(true);
            }
        }
        
        
        useEffect(() => {
            if (firstRender) return null;
    
            const getSearch = async () => {
                const searchValue = queryString.parseUrl(location.search);
                const { s } = searchValue.query;
                if(s === undefined) return null;
                    
                const response = await fetch(`${URL_API}/search/movie?api_key=${API_KEY}amp;language=es-ESamp;query=${s}amp;page=${page}` );
                const movies = await response.json();
                // console.log(movies)
    
                if (movies.results.length === 0) {
                    setShowNoResult(true);
                    setShowMovieList(false);
                } else {
                    setShowNoResult(false);
                    setPageTotal(movies.total_pages);
                    setMovieList(movies.results);
                }
            }
           
            getSearch();
            // eslint-disable-next-line   
        }, [location.search, page])
    
        return (
            <>
                <Grid container spacing={0} alignItems="center" className={classes.bigContainer}>
                    <Grid item xs={5} sm={4} md={3} className={classes.smallContainer} >
                        <Logo className={classes.media} />
    
                        <form 
                            className={classes.root} 
                            noValidate autoComplete="off"
                            onSubmit={ (e) => e.preventDefault() }
                        >
                    
                            <TextField 
                                id="outlined-basic" 
                                label="Buscar pelicula..." 
                                variant="outlined" 
                                className={classes.textField}
                                onChange={ handleInputChange }
                            />
                           
                        </form>
    
                    </Grid>
                </Grid>
    
                <Container >
                    <Grid container spacing={2} alignItems="center">
                        {
                            (showMovieList || movieList.length===0 ) ? (
                                movieList.length === 0 ? null  : (
                                    movieList.map( (movie) => (
                                        <Grid item xs={12} sm={6} md={3} key={movie.id} >
                                            <MovieCardItem movie={movie} key={movie.id} />
                                        </Grid>
                                    ))
                                )
                            ) : (null)
                        }
                        {
                            showNoResult amp;amp; <p className={classes.noResults}>No hay resultados para mostrar</p>
                        }
                    </Grid>
                </Container>
    
                {
                    (showPagination amp;amp; pageTotal > 1 amp;amp; !showNoResult ) amp;amp; 
                        (
                            <PaginationComp pageTotal={pageTotal} setPage={setPage} page={page} />
                        )
                }
            </>
        );
    }

 

А это кнопка моего нового фильма

 
    <Button 
        variant="contained" 
        color="primary"  
        href="#contained-buttons"
        size="large"
        component="div"
        onClick={() => history.goBack()}
    >
                                Volver
                            </Button>

 

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

1. вся выборка зависит только от местоположения.поиск, включает текущую страницу, разбиение на страницы.страница, текстовое поле.Значение по умолчанию инициализировано из местоположения.поиск, Разбиение на страницы.setPage, текстовое поле. Местоположение триггера onChange.нажмите, чтобы изменить URL-адрес

2. Теоретически, все поиски основаны на URL-адресе и отслеживают изменения в URL-адресе. Все значения инициализации компонентов берутся из URL-адреса, и URL-адрес напрямую изменяется при изменении значения компонента

3. в вашем случае невыполнение работы может привести к if (firstRender) return null; удалению этой строки и текстового поля. При обмене отмените изменение местоположения.поиск, кажется, в порядке

Ответ №1:

Когда вы удаляетесь, ваша страница поискового компонента размонтирована, и history.goBack() ваш компонент страницы будет повторно смонтирован, так что это то же самое, что и рендеринг новой страницы.

Для решения вам может потребоваться обновить параметр URL-запроса синхронизации, в то время как пользователь вводит «нравится», когда пользователь вводит action «нравится». /movie/search?q=action

В качестве альтернативы вы можете сохранить поиск пользователя в локальном хранилище или около того и прочитать значение, когда пользователь войдет на страницу поиска.