reactjs - 当我使用 history.goBack() 时,我无法从查询中触发 useEffect
问题描述
我正在学习 react 和 materialUI,以及我正在构建的应用程序关于在 amdb api 中搜索并带来一些数据。
在我的“搜索组件”中,我将其设置为当用户自动编写某些内容时,它会自动写入查询并使用此查询触发 useEffect。
第一次搜索效果很好,我列出了所有结果,你可以继续看你想要的电影。这将你带到其他组件,renderMovie,它有一个上一页的按钮(我使用 history.goBack() 设置它)
当我回去时出现问题;我确实回到了搜索组件,但我丢失了之前所做的搜索。我在 url 上有查询,但我无法触发 useEffect。
我尝试更改效果中的依赖项,但似乎没有任何效果。我也尝试过使用useMemo,但我无法让它工作,因为我本身没有函数(我的意思是我唯一的函数是handleInputChange)。
你能给点建议吗?我怎么能做到?我可以使用什么方法?或者你能给我其他的想法来尝试吗?
提前致谢!
这是我的 seachComponent,如果您有任何问题...
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: {
'& > *': {
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}&language=es-ES&query=${s}&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 && <p className={classes.noResults}>No hay resultados para mostrar</p>
}
</Grid>
</Container>
{
(showPagination && pageTotal > 1 && !showNoResult ) &&
(
<PaginationComp pageTotal={pageTotal} setPage={setPage} page={page} />
)
}
</>
);
}
这是我的 renderMovie 的按钮
<Button
variant="contained"
color="primary"
href="#contained-buttons"
size="large"
component="div"
onClick={() => history.goBack()}
>
Volver
</Button>
解决方案
当导航离开时,您的 searchComponent 页面被卸载,并将history.goBack()
重新安装您的页面组件,因此与渲染新页面相同。
对于解决方案,您可能需要在用户输入时更新同步 url-query 参数,例如当用户输入时action
您将 url 更新为喜欢/movie/search?q=action
或者,您可以将用户搜索保留在 localStorage 左右,并在用户进入搜索页面时读取该值。
推荐阅读
- google-cast - 使用 HLS 的 AC-3 和 E-AC-3 直通
- python - 在列表上的元组上使用函数在 Google Colab 中有效,但在本地机器上无效
- java - 如何在 Android Studio 中使用 Spinner 获取 RecyclerView 的结果
- tinymce - 为什么 TinyMCE 需要 API 密钥?
- php - 联系表格未发送消息
- python - Selenium webdriver 消息:没有这样的元素:无法找到元素 - iFrame
- javascript - javascript过滤json并返回另一个值
- dependencies - 查找 Common Lisp 文件之间的依赖关系
- c# - 有没有办法反转文件的每 2 个字节?
- java - r2dbc 连接关闭异常