前端 路由权限react
In this tutorial, we will go over how to build a complete front end app with routing and authentication.
在本教程中,我们将介绍如何使用路由和身份验证来构建完整的前端应用程序。
I have structured this tutorial and project as basically a boilerplate project with basic routing and auth that can be used as a starter project.
我已将本教程和项目基本上构造为具有基本路由和auth的样板项目,可用作入门项目。
If you just want the boiler plate code without the explanations here it is:https://github.com/iqbal125/react-hooks-routing-auth-starter
如果您只是想要没有说明的样板代码,则为: https : //github.com/iqbal125/react-hooks-routing-auth-starter
I will use Auth0 for authentication, but this setup will work with any other token-based authentication system as well.You can watch a fullstack video version of this tutorial herehttps://www.youtube.com/playlist?list=PLMc67XEAt-yzxRboCFHza4SBOxNr7hDD5
我将使用Auth0进行身份验证,但此设置也可以与任何其他基于令牌的身份验证系统一起使用。您可以在此处https://www.youtube.com/playlist?list=PLMc67XEAt-观看本教程的完整视频版本yzxRboCFHza4SBOxNr7hDD5
Connect with me on Twitter for more updates on future tutorials: https://twitter.com/iqbal125sf
在Twitter上与我联系以获取未来教程的更多更新: https : //twitter.com/iqbal125sf
目录 (Table of Contents)
- Project Structure 项目结构
- useReducer vs useState for Global Context state useReducer与useState的全局上下文状态
- Global State with Context 具有上下文的全局状态
- Authentication and authcheck 身份验证和授权检查
- React Hooks Components React Hooks组件
- Routing 路由
- App.js App.js
项目结构 (Project Structure)
I will first go over the structure of our app. Our app can be broken down into 4 parts:
我将首先介绍我们应用程序的结构。 我们的应用程序可以分为4部分:
- React hooks functional components React钩子功能组件
- Reducers and Actions 减速器和动作
- Utility files 实用程序文件
- Main files 主要档案
We will also need 4 libraries to build our app
我们还将需要4个库来构建我们的应用程序
npm install auth0-js react-router react-router-dom history
npm install auth0-js react-router react-router-dom history
目录结构: (Directory Structure:)
React Hooks功能组件 (React Hooks functional components)
Here we have our React Hooks functional components. We have a fairly simple setup and we will not be using any React Class components in this app.
在这里,我们有我们的React Hooks功能组件。 我们的设置非常简单,我们不会在此应用程序中使用任何React Class组件。
callback.js: will be used as the component that Auth0 will redirect to after the user authenticates.
callback.js:将用作用户验证后Auth0重定向到的组件。
header.js: will contain the links to the components and a login or logout button based on the user authentication state.
header.js:将包含指向组件的链接以及基于用户身份验证状态的登录或注销按钮。
home.js: will simply display the text of home.
home.js:只会显示home的文本。
hook1.js: will contain all three ways to update state with React hooks, useState
, useReducer
and useContext
. Having all three ways to update the state in one component will make it easier for you to pick apart the differences between each.
hook1.js:将包含所有三种使用React钩子更新状态的方法: useState
, useReducer
和useContext
。 具有在组件中更新状态的所有三种方法,将使您更容易区分每个组件之间的差异。
hooks_form1.js: Will have a form that has all three ways to update state with useState
, useReducer
and useContext
.
hooks_form1.js:将具有一种形式,该形式具有使用useState
, useReducer
和useContext
更新状态的所有三种方式。
privatecomponent.js: A component that is only accessible by authenticated users.
privatecomponent.js:只能由经过身份验证的用户访问的组件。
profile.js: A user dashboard that displays user profile data.
profile.js:一个显示用户个人资料数据的用户仪表板。
减速器和动作文件 (Reducers and Actions files)
action_types.js: Will hold all the string actions types in variables. This will allow easy modifying of your action types since you will only have to change them here instead having to track down where ever you used the action in your code.
action_types.js:将所有字符串操作类型保存在变量中。 这将使您可以轻松地修改操作类型,因为您只需在此处进行更改即可,而不必跟踪您在代码中使用过操作的位置。
actions.js: Will hold the actual actions that are going to be used in the reducer to update the state.
actions.js:将保存将在reducer中用于更新状态的实际操作。
auth_reducer.js: Will hold the reducer to read and update state properties related authentication.
auth_reducer.js:将持有化简器以读取和更新与身份验证相关的状态属性。
form_reducer.js: Will hold the reducer to read and update state properties related to our form.
form_reducer.js:将持有化简器以读取和更新与表单相关的状态属性。
plain_reducer.js: Will serve as a boilerplate reducer.
plain_reducer.js:将用作样板还原器。
实用程序文件 (Utility Files)
We will also need 4 utility files to help setup our app.
我们还将需要4个实用程序文件来帮助设置我们的应用程序。
context.js: Will hold the Context object and will be imported to every component that uses the useContext() hook.
context.js:将保存Context对象,并将其导入使用useContext()挂钩的每个组件中。
auth.js: This will be the only class in the app. Note that this isn’t a React class component, but instead a vanilla javascript class. I tried to setup this file as an arrow function but it did not work well. This file is best setup as a class. This file will hold all of our authentication associated functions and variables.
auth.js:这将是应用程序中的唯一类。 请注意,这不是React类的组件,而是普通的javascript类。 我试图将此文件设置为箭头功能,但效果不佳。 最好将此文件设置为类。 该文件将包含我们所有与身份验证相关的功能和变量。
history.js: Will hold the history object which we will use for navigation.
history.js:将保存用于导航的历史记录对象。
authcheck.js: Will be used to update the authentication state of the user and retrieve the user profile data and save it to the global state.
authcheck.js:将用于更新用户的身份验证状态并检索用户配置文件数据并将其保存为全局状态。
主要档案 (Main Files)
These are the main files and will sit at the root /src directory. I put all the business logic for reading and updating the global state in one file, the context_state_config.js
. My reason for doing so is follows.
这些是主要文件,位于/ src根目录中 。 我将所有用于读取和更新全局状态的业务逻辑放在一个文件context_state_config.js
。 我这样做的原因如下。
Having all the complexity in one file actually makes your app simpler and easier to debug since it's easy to track down where to make the changes and fixes.
将所有复杂性放在一个文件中实际上使您的应用程序更简单,更容易调试,因为它很容易跟踪更改和修复的位置。
Having many slightly complex components in my experience will actually make your app harder to debug and change. So for this reason I put all the global state code in this one file.
根据我的经验,拥有许多稍微复杂的组件实际上会使您的应用更难以调试和更改。 因此,出于这个原因,我将所有全局状态代码放入此文件中。
Also in the context_state_config.js
the <Routes />
component will be wrapped by the <Context.Provider />
. This will allow the ability to read and update state to be passed down through the value
prop to all the components, creating a global state.
同样在context_state_config.js
, <Routes />
组件将由<Context.Provider />
包装。 这将允许通过value
道具向下传递和读取状态的能力传递给所有组件,从而创建全局状态。
context_state_config.js: This will hold all the logic for reading and updating the global state with the useReducer
hook and context
.
context_state_config.js:这将保留使用useReducer
钩子和context
读取和更新全局状态的所有逻辑。
routes.js: Will contain all our routing logic and will have silent authentication here as well.
route.js:将包含我们所有的路由逻辑,并在此处也具有静默身份验证。
App.js: Our root component, we will simply import and display our context_state_config.js
component.
App.js:我们的根组件,我们将简单地导入并显示我们的context_state_config.js
组件。
index.js: Our root file, will just render App.js here.
index.js:我们的根文件将在此处呈现App.js。
useRedux与useState的全局上下文状态 (useRedux vs useState for Global Context state)
To manage global state we will be using Reducers and Actions. Using Reducers and Actions along with the useReducer()
hook and Context will allow us to achieve Redux like functionality without actually using Redux.
为了管理全局状态,我们将使用Reducers和Actions 。 结合使用useReducer()
和Actions以及useReducer()
钩子和Context将使我们无需实际使用Redux就可以实现类似Redux的功能。
It is possible to manage our global state with the useState
hook and Context, but using useReducer
makes managing global state much more organized. The useState
hook is far better at handling local component state.
可以使用useState
钩子和Context管理我们的全局状态,但是使用useReducer
可以更加有组织地管理全局状态。 useState
挂钩在处理本地组件状态方面要好得多。
Having related properties of state and all the update state functions in the same useReducer
hook makes things very simple and compartmentalized compared to using the useState
hook which can be much more decentralized.
与使用useState
钩子相比,在同一个useReducer
钩子中具有状态的相关属性和所有更新状态函数,使事情变得非常简单和分隔化。
Dispatching actions also makes the data flow easier to follow compared to using the setState
function from useState
since each action will describe exactly how the state will be changed.
与使用useState
的setState
函数相比, 分派操作还使数据流更易于遵循,因为每个操作将准确描述状态的更改方式。
We also dont need to use the combine reducer function or combine our reducers in anyway. Each reducer will be passed into its own useReducer hook.
我们也不需要使用组合减速器功能或以任何方式组合我们的减速器。 每个减速器将传递到其自己的useReducer钩子中。
通过上下文建立全局状态 (Setting up the Global State with Context)
We can begin by setting up the global state, which in my opinion makes it much easier to build the React Components.
我们可以从设置全局状态开始,我认为这使构建React组件变得更加容易。
If you already setup the global state you can build out the component in a very straightforward way instead having to go back and forth between setting up the component and then setting up its state along with it.
如果已经设置了全局状态,则可以以非常直接的方式构建组件,而不必在设置组件与设置状态之间来回移动。
To setup the global state we will ne