React Router - не удается прочитать «историю» свойств неопределенного

Я создаю приложение для руководства по стилю. У меня есть два выпадающих компонента, в которых пользователь может выбрать как бренд, так и компонент — затем приложение отобразит выбранный компонент под брендом в соответствии с выбранным брендом. Я хочу, чтобы обе эти опции были включены в URL-адрес.

Два раскрывающихся списка, которые программно меняют маршрут. Я получаю сообщение об ошибке TypeError: Не удается прочитать историю свойства undefined всякий раз, когда пользователь взаимодействует с раскрывающимся списком.

У меня есть компонент, отображаемый маршрутом:

<Route path = "/:brand/:component"
render = {props => <DisplayComponent {...props} />} />

Этот компонент имеет два обработчика событий для двух раскрывающихся компонентов, которые позволяют пользователю выбрать корень:

  handleComponentPick(event: any) {
    const component = event.target.value;
    this.props.history.push(`/${this.props.match.params.brand}/${component}`);
  }

  handleBrandChange = (event: any) => {
    if (event.target instanceof HTMLElement) {
      const brand = event.target.value;
      this.props.history.push(`/${brand}/${this.props.match.params.component}`);
    }
  };
  render = () => {
    return (
      <div className = {"constrain-width-wide center "}>
        <ThemePicker
          component = {this.props.match.params.component}
          brand = {this.props.match.params.brand}
          handleBrandChange = {this.handleBrandChange}
          handleComponentPick = {this.handleComponentPick}
        />
        <div className = "currently-selected-component" />
        <Route path = "/:brand/button" component = {Button} />
        <Route path = "/:brand/card" component = {Card} />
      </div>
    );
  };
}

Я оборачиваю все приложение в Router.

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById("root")
);```
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
10 209
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Можете ли вы попробовать эти следующие изменения handleComponentPick(event: any) { к handleComponentPick = (event: any) => { тогда render = () => { к render() { Надеюсь, это сработает.

вы должны пройти историю, как

  <Router history = {browserHistory} routes = {routes} />,

таким образом, вы можете использовать историю с реквизитами для навигации.

шрифт: https://github.com/ReactTraining/react-router/blob/v3/docs/guides/Histories.md

попробуйте использовать browserHistory на вашем app.js, например

render(
  <Router history = {browserHistory}>
    <Route path='/' component = {App}>
      <IndexRoute component = {Home} />
      <Route path='about' component = {About} />
      <Route path='features' component = {Features} />
    </Route>
  </Router>,
  document.getElementById('app')
)

таким образом, вы передаете историю для всего вашего другого маршрутизатора.

Нам нужно передать history в качестве опоры для Router. Я ожидаю, что вы используете реагирующий маршрутизатор v4, также известный как react-router-dom.

import { createBrowserHistory } from "history";
import { Router } from "react-router-dom";


const history = createBrowserHistory();

    ... 

<Router history = {history}>
     <Routes />
</Router>

Демонстрация: https://codesandbox.io/s/yv5y905ojv

Подсмотрел хук useHistory() и предоставил данные о фиктивном маршруте.

import routeData from 'react-router';

describe('<Component /> container tests', () => {

  beforeEach(() => {
    const mockHistory = {
      pathname: '/dashboard'
    };
    jest.spyOn(routeData, 'useHistory').mockReturnValue(mockHistory);
  });

Если вы получаете эту ошибку в тесте с использованием jest, вам нужно обернуть свой компонент в маршрутизатор. Я использую библиотека для тестирования реакции, поэтому моя логика выглядит следующим образом:

import { render, cleanup } from '@testing-library/react'
import { BrowserRouter as Router } from 'react-router-dom'
import YourComponent from '../path/to/YourComponent'

// ...
describe('YourComponent component', () => {
  afterEach(cleanup)
  it('matches snapshot', () => {
    const { asFragment } = render(
      // The following will solve this issue
      <Router>
        <YourComponent />
      </Router>
    )
    expect(asFragment()).toMatchSnapshot()
  })
})

Другие вопросы по теме