#javascript #reactjs #react-router-dom
#javascript #reactjs #react-router-dom
Вопрос:
У меня есть поле ввода автозаполнения в моем приложении react, основанное на выборе пользователя, react-router перенаправит на страницу сведений о продукте.
Мой путь к странице сведений о продукте структурирован, как показано ниже:
<Route extact path={'/:category/:id'} component={ProductDetailContainer}/>
В моем автозаполнении у меня есть onChange
функция, которая запускает перенаправление.
const handleChange(event, value) => {
history.push(`${value.category}/${value.id}`)
}
Хотя это работает, когда пользователь находится в базовом URL-адресе '/'
, это приведет к сбою, если пользователь попытается использовать поле автозаполнения в ProductDetailContainer
из-за того, что путь был добавлен поверх текущего пути снова, тогда он станет таким путем '/:PrevCategory/:NewCategory/:id'
Я пытался использовать replace
, но, похоже, он делает то же самое. Итак, есть ли способ сбросить историю до базового URL перед push ()?
#Редактировать 1 Здесь поле автозаполнения и история являются push.
import React from 'react';
import { useHistory } from "react-router-dom"
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import { fade, makeStyles } from '@material-ui/core/styles';
import MenuIcon from '@material-ui/icons/Menu';
import TextField from '@material-ui/core/TextField'
import CircularProgress from '@material-ui/core/CircularProgress'
import Autocomplete from '@material-ui/lab/Autocomplete'
const useStyles = makeStyles((theme) => ({
....
}));
const TitleBar = () => {
const classes = useStyles();
const history = useHistory();
const [open, setOpen] = React.useState(false);
const [options, setOptions] = React.useState([]);
const loading = open amp;amp; options.length === 0;
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined
}
(async () => {
const response = await fetch(site)
const products = await response.json();
if (active){
setOptions(products)
}
})();
return () => {
active = false;
};
}, [loading])
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open])
const handleChange = (event, value) => {
if (value !== null) {
// redirect to product detail page if user selected an item
history.replace(`${value.category}/${value.id}`)
}
}
return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="open drawer"
>
<MenuIcon />
</IconButton>
<div className={classes.search}>
<Autocomplete
id='aysncSearchBar'
style={{ width : 300}}
open={open}
onOpen={()=>{setOpen(true)}}
onClose={()=>{setOpen(false)}}
getOptionSelected={(option, value) => option.id = value.id}
getOptionLabel={(option) => option.title}
options={options.sort((a,b) => -b.category.localeCompare(a.category))}
groupBy={(option) => option.category}
loading={loading}
onChange={handleChange}
renderInput={(params) => (
<TextField
{...params}
label="Search"
variant="outlined"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
/>
)}
/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default TitleBar;
Комментарии:
1. Как вы получаете свой объект истории?
2. const history = useHistory(); если это то, что вы спрашиваете. Я следовал инструкциям с сайта маршрутизатора react reactrouter.com/web/api/Hooks/usehistory
3. Также хотелось бы видеть ваш компонент с JSX. Отредактируйте вопрос, чтобы включить оба 🙂
4. хм, отлично. Позвольте мне посмотреть, что происходит. Надеюсь на лучшее, мой друг 🙂
5. Конечно, добавлен компонент.
Ответ №1:
/
При нажатии вам не хватает базы .. если у вас нет базы /
, il продолжит добавление.
history.push(`/${value.category}/${value.id}`)
Комментарии:
1. о, вау, я не могу поверить, что пропустил эту часть. Ценю вашу помощь!
2. Рад, что смог вам помочь 🙂 Пожалуйста, не забудьте проголосовать 🙂