Я создаю приложение для руководства по стилю. У меня есть два выпадающих компонента, в которых пользователь может выбрать как бренд, так и компонент — затем приложение отобразит выбранный компонент под брендом в соответствии с выбранным брендом. Я хочу, чтобы обе эти опции были включены в 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")
);```



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Можете ли вы попробовать эти следующие изменения
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()
})
})