gpt4 book ai didi

javascript - 将基于 React 路由器 v4 类的代码重写为基于 v6 功能的代码

转载 作者:行者123 更新时间:2023-12-05 04:39:48 25 4
gpt4 key购买 nike

我正在尝试使用 react 和 spring boot 实现 oauh 登录,我找到了一个我可以遵循的教程。

我遇到的问题是它使用的是 React Router v4,我想更新它以使用 React Router v6 并改为使用 Functional 组件。

登录.js

import React, { Component } from 'react';
import './Login.css';
import { GOOGLE_AUTH_URL, FACEBOOK_AUTH_URL, GITHUB_AUTH_URL, ACCESS_TOKEN } from '../../constants';
import { login } from '../../util/APIUtils';
import { Link, Redirect } from 'react-router-dom'
import fbLogo from '../../img/fb-logo.png';
import googleLogo from '../../img/google-logo.png';
import githubLogo from '../../img/github-logo.png';
import Alert from 'react-s-alert';


class Login extends Component {
componentDidMount() {
// If the OAuth2 login encounters an error, the user is redirected to the /login page with an error.
// Here we display the error and then remove the error query parameter from the location.
if(this.props.location.state && this.props.location.state.error) {
setTimeout(() => {
Alert.error(this.props.location.state.error, {
timeout: 5000
});
this.props.history.replace({
pathname: this.props.location.pathname,
state: {}
});
}, 100);
}
}

render() {
if(this.props.authenticated) {
return <Redirect
to={{
pathname: "/",
state: { from: this.props.location }
}}/>;
}

return (
<div className="login-container">
<div className="login-content">
<h1 className="login-title">Login to SpringSocial</h1>
<SocialLogin />
<div className="or-separator">
<span className="or-text">OR</span>
</div>
<LoginForm {...this.props} />
<span className="signup-link">New user? <Link to="/signup">Sign up!</Link></span>
</div>
</div>
);
}
}

class SocialLogin extends Component {
render() {
return (
<div className="social-login">
<a className="btn btn-block social-btn google" href={GOOGLE_AUTH_URL}>
<img src={googleLogo} alt="Google" /> Log in with Google</a>
<a className="btn btn-block social-btn facebook" href={FACEBOOK_AUTH_URL}>
<img src={fbLogo} alt="Facebook" /> Log in with Facebook</a>
<a className="btn btn-block social-btn github" href={GITHUB_AUTH_URL}>
<img src={githubLogo} alt="Github" /> Log in with Github</a>
</div>
);
}
}

App.js

  • 这是带有路由的 App.js,我已将其更新为使用 Functional 组件和 React Router v6。
//imports left out

function App() {

const [globalUserState, setGlobalUserState] = useState({
authenticated: false,
currentUser: null,
loading: true
});

useEffect(() => {
loadCurrentlyLoggedInUser();
})

const loadCurrentlyLoggedInUser = () => {
getCurrentUser()
.then(res => {
setGlobalUserState({
currentUser: res,
authenticated: true,
loading: false
});
}).catch(err => {
setGlobalUserState({
loading: false
})
})
}

const handleLogout = () => {
localStorage.removeItem(ACCESS_TOKEN);
setGlobalUserState({
authenticated: false,
currentUser: null
});
Alert.success("You're safely logged out!");
}


return (
<Router>
<div className="app">

<div className="app-header">
<AppHeader />
</div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/profile" element={<SecuredRoute> <Profile /> </SecuredRoute>} />
<Route path="/login" element={(props) => <Login authenticated={globalUserState.authenticated} {...props} />} />
<Route path="/signup" element={(props) => <Signup authenticated={globalUserState.authenticated} {...props} />} />
<Route path="/oauth2/redirect" element={<OAuth2RedirectHandler />} />
<Route path="*" element={<Notfound />} />
</Routes>

<Alert stack={{limit: 3}}
timeout = {3000}
position='top-right' effect='slide' offset={65}
/>
</div>
</Router>
);
}

export default App;


我想澄清什么

  1. 我正在努力理解 v6 的 React 路由器功能(location.state.error、history.replace、location.pathname 等)和功能组件而不是基于类的等价物。

  2. 此外,如果有人可以解释这一行,请 <LoginForm {...this.props} />

最佳答案

Q1

I'm struggling to understand the equivalent of the react routerfunctionalities with v6 (location.state.error, history.replace,location.pathname etc) and functional components instead of classbased.

react-router-dom v6 不再有路由 Prop ,即没有 history , location , 没有 match . Route组件也不再有 componentrender引用 React 组件或返回 JSX 的函数的 props,它们被 element 替换了采用 JSX 文字的 prop,即 ReactElement。

如果我正确理解了你的问题,你是在问如何使用 RRDv6 类组件 LoginSignup .

你有几个选择:

  1. 转换 LoginSignup也进入 React 功能组件并使用新的 React Hook 。

    我不会介绍转换,但要使用的钩子(Hook)是:

    • useNavigate - history对象被替换为 navigate功能。

      const navigate = useNavigate();

      ...

      navigate("....", { state: {}, replace: true });
    • useLocation

      const { pathname, state } = useLocation();
  2. 创建自定义 withRouter可以使用钩子(Hook)并将它们作为 props 传递下去的组件。

    const withRouter = WrappedComponent => props => {
    const navigate = useNavigate();
    const location = useLocation();
    // etc... other react-router-dom v6 hooks

    return (
    <WrappedComponent
    {...props}
    navigate={navigate}
    location={location}
    // etc...
    />
    );
    };

    装饰 LoginSignup导出:

    export default withRouter(Login);

    this.props.history.push 交换至 this.props.navigate :

    componentDidMount() {
    // If the OAuth2 login encounters an error, the user is redirected to the /login page with an error.
    // Here we display the error and then remove the error query parameter from the location.
    if (this.props.location.state && this.props.location.state.error) {
    setTimeout(() => {
    const { pathname, state } = this.props.location;
    Alert.error(state.error, { timeout: 5000 });
    this.props.navigate(
    pathname,
    { state: {}, replace: true }
    );
    }, 100);
    }
    }

剩下的就是修复App中的路由所以他们正确地呈现 JSX。

<Router>
<div className="app">
<div className="app-header">
<AppHeader />
</div>
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/profile"
element={(
<SecuredRoute>
<Profile />
</SecuredRoute>
)}
/>
<Route
path="/login"
element={<Login authenticated={globalUserState.authenticated} />}
/>
<Route
path="/signup"
element={<Signup authenticated={globalUserState.authenticated} />}
/>
<Route path="/oauth2/redirect" element={<OAuth2RedirectHandler />} />
<Route path="*" element={<Notfound />} />
</Routes>

<Alert stack={{limit: 3}}
timeout = {3000}
position='top-right' effect='slide' offset={65}
/>
</div>
</Router>

Q2

Also, If someone can explain this line please <LoginForm {...this.props} />

这只是获取传递给父组件的所有 Prop 并复制/传递给 LoginForm组件。

<LoginForm {...this.props} />

Login通过了 authenticated prop 以及注入(inject)的任何新“路由 props”,以及您可能正在使用的任何其他 HOC 注入(inject)的任何其他 props,以上将它们全部传递给 LoginForm .

关于javascript - 将基于 React 路由器 v4 类的代码重写为基于 v6 功能的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70392968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com