#reactjs #routes #react-router #react-router-dom #history
Вопрос:
У меня есть функция, которую я хочу, чтобы она заменяла компоненты между Header
компонентами и Footer
компонентами.
Где/как я должен использовать defaultRouter
функцию с history.push
. Я вижу, что изменен только URL-адрес.
Header
Компонент обновляет pageIndex
.
Я попытался переключиться defaultRouter
на useCallback
функцию, но это совсем не сработало.
Каков порядок выполнения функций диссертаций? App.js
function App() {
const [searchResults, setSearchResults] = useState([]);
const [itemsAmount, setItemsAmount] = useState('');
const [pageIndex, setPageIndex] = useState();
const history = createBrowserHistory();
// let history = useHistory();
const defaultRouter = useMemo(() => {
console.log(pageIndex);
switch (pageIndex) {
case 1:
history.push({ pathname: '/search', state: searchResults });
break;
case 2:
history.push('/cart');
break;
default:
history.push('/');
break;
}
}, [pageIndex]);
return (
<div className='App'>
<Header
settingResults={setSearchResults}
itemsCartAmount={itemsAmount}
setPageIndex={setPageIndex}
/>
{defaultRouter}
<Footer />
<Router history={history}>
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/search'>
<Search/>
</Route>
<Route path='/cart'>
<Cart />
</Route>
<Route component={PageNotFound} />;
</Switch>
</Router>
</div>
);
}
Редактировать
Я только что удалился BrowserRouter
из Index.js, та же проблема.
Index.js
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
Этот способ выше pageIndex
-обновление, но history.push
не переключайте компоненты.
Комментарии:
1. Можете ли вы объяснить, почему вы используете 2 маршрутизатора в своем приложении ?
2. Привет @kumarmo2 , это было сказано мне в предыдущем моем вопросе, я просто удалил » <BrowserRouter>` в <BrowserRouter>
Index.js
. Та же проблема и здесь.
Ответ №1:
Я думаю, что здесь происходит то, что history
объект создается каждый раз, когда pageIndex
он обновляется. В идеале он должен быть создан только один раз вручную.
Вы можете найти рабочее решение здесь.
- логика создания объекта истории
- удалено
Router
из приложения - используется
useHistory
для получения объекта истории в компоненте. - также написал эффект для внесения изменений при
pageIndex
обновлении.
Комментарии:
1. Спасибо, я проверяю это прямо сейчас. У меня есть вопрос —
useEffect
будетHome
ли компонент отображаться еще раз после первого рендеринга, могу ли я это предотвратить ?2. Я не уверен, почему вы используете
pageIndex
, но я бы на самом деле избавился отpageIndex
. По нажатию кнопок я бы сделал это напрямуюhistory.push
, а не устанавливал состояние. и как только мы избавимсяpageIndex
, эффект тоже исчезнет3. В моем Index.js Я завернул свое приложение
BrowserRouter
так же, как и вы, но изменился только URL-адрес.4. Итак, как я буду использовать
history.push
внутриHeader
, когда все маршруты будут в APP.js ? безpageIndex
.5. если вы заметили, я создал
history
объект вне любого компонента. Это гарантирует, что объект истории будет создан только один раз. вы создавали объект истории внутриApp
, что означает, что каждый раз, когда состояние обновляется, создается новый объект истории
Ответ №2:
пожалуйста, взгляните на это, я попытался воспроизвести вашу проблему.
https://codesandbox.io/s/amazing-swartz-jxc5p?file=/src/App.jsВы использовали маршрутизатор дважды, один внутри App.js
as <Router>
, а другой внутри index.js
as <BrowserRouter>
. Что вам нужно сделать, так это использовать только внутри App.js и убедитесь, что он импортирован как:
import {Router} from 'react-router-dom';
поскольку маршрутизатор принимает поддержку истории, а не браузер, а также удаляет BrowserRouter
из index.js
.
Для более безопасной стороны используйте useHistory()
крючок для значения истории.
Это устранит вашу проблему.
Комментарии:
1. Я снял
BrowserRouter
с index.js, по-прежнему меняется только URL-адрес на/search
2. @ExtraSun пожалуйста, проверьте обновленный ответ, я прикрепил ссылку на codesandbox. Я попытался повторить вашу проблему.
3. Использование
let history = useHistory()
— ` return ( <имя класса div=’Приложение’ <История маршрутизатора={история}>` приводит к ошибке <История маршрутизатора={история}>TypeError: Cannot read property 'push' of undefined.
Ваш код в codesandbox.io изменяет только URL — адрес, а не компонент.4. Я проверил его, и он тоже переключал компоненты. В любом случае, не могли бы вы обновить свой код со всеми
import
инструкциями, там может быть проблема.5. Странно, потому что я вижу только «Образец» при нажатии на кнопки, а не
<h1> Cart </h1>;