Lo siento si esta es una pregunta tonta, pero estoy tratando de mejorar mis habilidades de reacción y crear un sitio simple con un menú desplegable de selección que debería dirigirse a una URL cuando se seleccione. Sin embargo, recibo este error. O si hay una mejor manera de hacer esto con ganchos, soy todo oídos :). Gracias
× TypeError: Cannot read properties of undefined (reading 'push') DropDown.onChange src/components/Dropdown.js:10 7 | 8 | class DropDown extends Component { 9 | onChange = (e) => { > 10 | this.props.history.push(`/${e.target.value}`); 11 | } 12 | 13 | render() {A continuación se muestra mi código
import React, { Component } from 'react' import '../App.css' import ReactDOM from 'react-dom'; import { BrowserRouter, Route, withRouter } from "react-router-dom"; class DropDown extends Component { onChange = (e) => { this.props.history.push(`/${e.target.value}`); } render() { return ( <div> <label htmlFor="pests">Choose a pest:</label> <select onChange={this.onChange}> <option value="ants">Ants</option> <option value="wasps">Wasps</option> </select> </div> ) } } export default DropDown;Aquí está mi código de enrutador
function App() { return ( <div className="main"> {/* <Navbar/> */} <Header /> <NavbarBasic /> <Dropdown /> {/* These are the main routes and subpages */} <Routes> <Route path='/' element={<Home />} /> <Route path='/about' element={<About />} /> <Route path='/pests-we-treat' element={<Pests />} /> <Route path='/services' element={<Services />} /> <Route path='/contact' element={<Contact />} /> <Route path='/ants' element={<Ants />} /> <Route path='/wasps' element={<Wasps />} /> </Routes> </div> ); } export default App;Transforme su componente de clase en un componente funcional e importe useHistory de esta manera:
import { useHistory } from "react-router-dom"; ... let history = useHistory(); history.push(`/${e.target.value}`); import React, { Component } from 'react'; // import { BrowserRouter, Route, withRouter } from "react-router-dom"; class DropDown extends Component { onChange = (e) => { // this.props.history.push(`/${e.target.value}`); window.location.href = `/${e.target.value}`; } render() { return ( <div> <label htmlFor="pests">Choose a pest:</label> <select onChange={this.onChange}> <option value="ants">Ants</option> <option value="wasps">Wasps</option> </select> </div> ); } } export default DropDown;Enrutador desplegable.tsx
import { createBrowserHistory } from 'history'; export default function DropdownPush(path: string) { let history = createBrowserHistory(); history.push(`/${path}`); }O
import { useHistory } from 'react-router-dom'; export default function DropdownPush(path: string) { const history = useHistory(); history.push(`/${path}`); }O si está utilizando v6 react-router-dom useHistory() fue reemplazado por useNavigate()
import { useNavigate } from "react-router-dom"; export default function DropdownPush(path: string) { const navigate = useNavigate(); navigate(`/${path}`); }menú desplegable.tsx
import React, { Component } from 'react'; import DropdownPush from './dropdownRouter'; class DropDown extends Component { constructor(props) { super(props); } onChange = (e) => { // this.props.history.push(`/${e.target.value}`); // JS redirect method // window.location.href = `/${e.target.value}`; // Using Hook DropdownPush(e.target.value); }; render() { return ( <div> <label htmlFor="pests">Choose a pest: </label> <select onChange={this.onChange}> <option value="ants">Ants</option> <option value="wasps">Wasps</option> </select> </div> ); } } export default DropDown;Espero que desee envolver su componente Dropdown en el componente de orden superior withRouter . Eso normalmente sucedería en la exportación:
import { withRouter } from "react-router"; class DropDown extends Component { // ... } export default withRouter(Dropdown); La forma alternativa de acceder al history es usar el gancho useHistory , y los documentos contienen un buen ejemplo de cómo usarlo.