Необработанное отклонение (ошибка типа): не удается прочитать свойства undefined (чтение ‘push’), используя useHistory

#javascript #reactjs #react-hooks

#javascript #reactjs #реагирующие крючки

Вопрос:

Я новичок в react js, при попытке извлечь страницу из разных компонентов с помощью (попытка извлечь компонент панели мониторинга из компонента loginform, а компонент loginform находится внутри целевой страницы) history.push() Я получаю эту ошибку.

(app.js )

 import React from "react";
import { BrowserRouter as Router,Route,Switch } from "react-router-dom";
import LandingPage from "./Pages/LandingPage/LandingPage";
import DashBoard from "./Pages/Dashboard/dashBoard";


export default function App(){
    return(
        
        <Router>
            <Switch>
                <Route exact path="/" component={LandingPage} />
                <Route exact path="/dashboard" component={DashBoard}/>
            </Switch>
        </Router>
    );
}
 

(страница входа)
здесь я столкнулся с проблемой в методе входа в систему

 import React, { useRef, useState,useEffect } from 'react';
import { gsap } from 'gsap';
import $ from 'jquery';
import swal from 'sweetalert';
import {useHistory,withRouter} from 'react-router-dom';

import './LF.css';
import LoginLogo from './zmtLogo.png';

var LoginForm = (props) => {

let history = useHistory();

var Login = async ()=>{
        if(LoginData.email !== '' amp; LoginData.pass!== ''){

            history.push("/dashboard")

        }else{
            swal({
                title: "Incomplite fillup",
                icon: "warning"
            });
        }
    }

    return (
        <>
            <div className="l_main" ref={LOGbox}>

                <div className="login">
                    <p>Login Here!</p>

                    <div className="fillup">
                        <i className="far fa-envelope"></i>
                        <input onChange={LoginFillup} value={LoginData.email} id="userid" name="userid" type="text" placeholder="Email" />
                    </div>

                    <div className="fillup">
                        <i className="fas fa-lock"></i>
                        <input onChange={LoginFillup} value={LoginData.pass} id="pass" name="pass" type="password" placeholder="password" />
                        <i className="fas fa-eye" id="eye"></i>
                    </div>

                    <button onClick={Login}>Login</button>
                    <p id="signup">don't have an account?<span id="click_1" onClick={LeftSlider}>create</span> </p>
                    <p id="fo_p">Forget password</p>

                    
                </div>
                {/* <!-- .................................................................................................. --> */}
                <div className="signup">
                    <p>Signup Here!</p>

                    <div className="fillup">
                        <i className="fas fa-users"></i>
                        <input onChange={signupFillup} value={SignUpData.userName} id="user_name" name="user_name" type="text" placeholder="name" />
                    </div>

                    <div className="fillup">
                        <i className="far fa-envelope"></i>
                        <input onChange={signupFillup} value={SignUpData.email} id="user_em" name="user_em" type="text" placeholder="email" />
                    </div>

                    <div className="fillup">
                        <i className="fas fa-lock"></i>
                        <input onChange={signupFillup} value={SignUpData.pass} id="user_pass" name="user_pass" type="password" placeholder="password" />
                    </div>

                    <div className="fillup">
                        <i className="fas fa-lock"></i>
                        <input onChange={signupFillup} value={SignUpData.pass2} id="user_pass_2" name="user_pass_2" type="password" placeholder="password(re type)" />
                    </div>

                    <button onClick={Signup}>Register</button>
                    <p id="login">Already have an account.<span id="click_2" onClick={RightSlider}>login</span> </p>

                   
                </div>
                {/* <!-- ................................................................................................--> */}
                <div className="slider">
                    <div className="img_area">
                        <div className="close_tab" onClick={props.closefunction}>
                            close
                        </div>
                        <div className="img_sec">
                            <img src={LoginLogo} alt="" />
                        </div>
                    </div>
                </div>

            </div>
        </>
    )
};

export default LoginForm;
 

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

1. Кажется, вам не хватает части кода страницы входа в систему, где вы объявляете history и где находится начало компонента?

2. извини, это моя вина. Я обновил его, пожалуйста, посмотрите.

3. Где LoginForm отображается? Это в пределах Router ?

4. его отображение внутри компонента landingpage

5. Я вижу, тогда использования useHistory крючка и объявления const history = useHistory(); должно быть достаточно. Вы убедились, что уничтожили какие-либо средства просмотра кода / горячие перезагрузки? Если проблема все еще сохраняется, думаете, вы могли бы создать небольшую демонстрационную версию codesandbox, которая воспроизводит проблему, которую мы могли бы проверять и отлаживать в реальном времени?

Ответ №1:

Я не совсем уверен, почему вы структурировали свой код как таковой, но LandingPage рендеринг the LoginForm в отдельный элемент DOM, отображаемый в a reactDom.render и, следовательно, не отображается в контексте маршрутизации. history действительно не определено.

 reactDom.render(
  <LoginForm closefunction={ClosePopup} />,
  document.getElementsByClassName("Lpopup")[0]
);
 

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

Целевая страница

Преобразуйте PopDisplay состояние в логическое значение, чтобы показать / скрыть «модальное», и условно отобразите раздел «Lpopup» и LoginForm .

 const [PopDisplay, setPopDisplay] = useState(false);

const DisplayPopup = () => {
  setPopDisplay(true);
};

const ClosePopup = () => {
  setPopDisplay(false);
};

...

{PopDisplay amp;amp; (
  <div className="Lpopup" style={{ display: "flex" }}>
    <LoginForm closefunction={ClosePopup} />
  </div>
)}
 

Теперь, когда это LoginForm отображается в том же приложении, оно должно иметь доступ к контексту маршрутизации, и useHistory перехват должен возвращать определенный history объект.

Редактировать необработанное отклонение typeerror-cannot-read-properties-of-undefined-reading-p

Ответ №2:

В react router dom v6 useHistory была заменена на usenavigate hook .

так и поступай

 import {useNavigate} from 'react-router-dom'

const App=()=>{
const history=useNavigate()
   return <>....</>
}
 

https://reactrouter.com/docs/en/v6/getting-started/overview
посмотри на это

Или понизьте версию react-router-dom, чтобы использовать перехват usehistory

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

1. Если бы это было так, что OP был на RRDv6, тогда Switch это не сработало бы, и было бы много ошибок, связанных с тем, что a не отображается Route в Routes компоненте, и ничто, отображаемое в element prop Route , useHistory не было бы определено и т. Д. И т. Д… Я не верю, что OP использует v6.

2. «react-router-dom»: «^ 5.3.0»,

3. после понижения версии до 5.2.0. все еще отображается та же ошибка