маршрут реакции — Как использовать историю.нажмите, чтобы переключить компоненты ? Меняется только URL-адрес

#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

Нажатие на кнопку 2

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

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>;