Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 路由/重定向不会在React路由器4&;中呈现;重复授权_Javascript_Reactjs_Authentication_Redux_React Router - Fatal编程技术网

Javascript 路由/重定向不会在React路由器4&;中呈现;重复授权

Javascript 路由/重定向不会在React路由器4&;中呈现;重复授权,javascript,reactjs,authentication,redux,react-router,Javascript,Reactjs,Authentication,Redux,React Router,我正在尝试使用React Router 4+Redux实现一个简单的授权流 我想要的行为 如果authorization(存储中的布尔值)为false,则任何路由都应该重定向到登录页面 如果授权为真,则任何路由都应呈现该路由 但是,如果在用户登录时请求登录路径,则应将其重定向到应用程序的根路径 我的实现 我已经创建了一个组件,我将它放在一个容器中(即react-redux-connect),用于访问存储中的授权布尔值 接受两个组件,和,并根据布尔值决定一个或另一个组件 在内部,根据授权,向

我正在尝试使用React Router 4+Redux实现一个简单的授权流

我想要的行为
  • 如果
    authorization
    (存储中的布尔值)为
    false
    ,则任何路由都应该重定向到登录页面
  • 如果
    授权
    ,则任何路由都应呈现该路由
  • 但是,如果在用户登录时请求登录路径,则应将其重定向到应用程序的根路径
我的实现
  • 我已经创建了一个组件
    ,我将它放在一个容器中(即react-redux-connect),用于访问存储中的
    授权
    布尔值
  • 接受两个组件,
    ,并根据布尔值决定一个或另一个组件
  • 内部,根据
    授权
    ,向请求的组件呈现
    ,或呈现
  • 中的表单将发送一个
    登录
    操作,该操作将
    授权
    布尔值设置为true
  • 中的表单将发送一个
    注销
    操作,该操作将
    授权
    布尔值设置为false。(此表单应与
    分开,但我将它们放在一起以保持示例的简单性。)
问题 我遇到的问题是,当存储更改时,组件似乎没有更新。硬刷新页面会更新视图,但它也会清除商店,而且只是有bug

我可能在某个地方做了一些错误的假设。如果有人能帮忙,我将不胜感激

代码 我已经创建了一个简化版本的代码,如下所示,可以粘贴到
createreact-app
app.js
文件中。下面是一个
package.json
文件,用于启动并运行它。(在我正在处理的版本中,身份验证被持久化到cookie中,因此刷新不会清除身份验证。)

除了可能提供的任何解决方案之外,我还想知道调试react应用程序的技巧,尤其是路由器

App.js:

// import Libs
import React, { Component } from "react"
import { BrowserRouter as Router, Route, Redirect } from "react-router-dom"
import { createStore, applyMiddleware } from "redux"
import { Provider, connect } from "react-redux"
import { createLogger } from "redux-logger"

const loggerMiddleware = createLogger()

// create Store/Reducer
const store = createStore((state = { authenticated: false }, action) => {
    switch (action.type) {
        case "LOGIN":
            return {
                authenticated: true
            }
        case "LOGOUT":
            return {
                authenticated: false
            }
        default:
            return state
    }
}, applyMiddleware(loggerMiddleware))

// <CheckAuth> component
const CheckAuth = ({ authenticated, location, LoginPage, Protected }) => {
    const { pathname } = location
    if (authenticated) {
        if (pathname === "/login") {
            return <Redirect to="/" />
        }
        return <Route path={pathname} component={Protected} />
    }
    if (pathname === "/login") {
        return <Route path="/login" component={LoginPage} />
    }
    return <Redirect to="login" />
}

const mapStateToProps = state => ({
    authenticated: state.authenticated
})

const CheckAuthContainer = connect(mapStateToProps)(CheckAuth)

// Log in and out Actions
const authenticate = () => ({
    type: "LOGIN"
})

const removeAuth = () => ({
    type: "LOGOUT"
})

// <Login> component
const Login = ({ dispatch }) => {
    const login = e => {
        e.preventDefault()
        dispatch(authenticate())
    }
    return (
        <form onSubmit={login}>
            <button type="Submit">Login</button>
        </form>
    )
}

// <LoginPage> component
const LoginContainer = connect()(Login)

const ProtectedPage = ({ dispatch }) => {
    const logout = e => {
        e.preventDefault()
        dispatch(removeAuth())
    }
    return (
        <div>
            <h1>Protected</h1>
            <form onSubmit={logout}>
                <button type="Submit">Logout</button>
            </form>
        </div>
    )
}

const ProtectedPageContainer = connect()(ProtectedPage)

class App extends Component {
    render() {
        return (
            <Provider store={store}>
                <Router>
                    <CheckAuthContainer
                        LoginPage={LoginContainer}
                        Protected={ProtectedPageContainer}
                        location={location}
                    />
                </Router>
            </Provider>
        )
    }
}

export default App
我想出来了

实际上直接解决了这个问题,但不知何故我误解了如何应用它

通过路由器将
组件传递到
解决了我的问题。第45行是这样的:

const CheckAuthContainer = withRouter(connect(mapStateToProps)(CheckAuth))
我还没有在我正在开发的真正的应用程序中尝试过这一点。希望它在那里也能起作用

const CheckAuthContainer = withRouter(connect(mapStateToProps)(CheckAuth))