如何使用 React 从应用程序中的任何位置获取组件
介绍
React 中的 UI 组件可以看作是一组 HTML 元素。Web 开发人员经常想知道是否可以将整个组件视为 DOM 元素并使用id或className引用它。当然,React 不是为此而构建的,但它确实允许您使用其路由来获取组件。本指南提供了一个具体的示例,该示例结合了 React-Router 和 Context API 的强大功能,可从应用程序中的任何位置调用组件。
示例应用程序概述和设置
此示例应用允许用户使用浏览器的localStorage API进行注册和登录。您将了解如何使用路由识别组件,并了解 Context API 在触发对这些组件的显式调用方面提供的便利。
创建一个空的 React 项目
通过运行以下命令创建一个新的 React 项目:
npx create-react-app react-router-context
添加 Bootstrap 样式
通过在 index.html 中添加以下行来使用 bootstrap:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
安装 React-Router
在根目录中运行以下命令来安装react-router-dom:
npm i react-router-dom
创建路线
该应用程序包含三个不同页面的三个路由:Login、Signup和Home。Home组件是用户成功登录后看到的内容。请考虑以下代码,它设置了应用程序的路由并一次渲染一个路由:
import React from 'react';
import {Route,BrowserRouter,Switch} from 'react-router-dom';
import Home from '../components/Home';
import Signup from '../components/Signup';
import Login from '../components/Login';
const Routes=()=>{
return(
<>
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/signup" component={Signup}/>
<Route exact path="/login" component={Login}/>
</Switch>
</BrowserRouter>
</>
);
}
export default Routes;
在任何时候,您都可以通过引用其路由从应用程序中的任何位置调用组件。
创建组件
Login组件包含一个引导表单,该表单有两个字段,分别用于输入用户的电子邮件和密码,以及用于存储它们的状态。它还包含一个用于设置状态的handleChange()方法和一个用于在控制台上注销此状态的handleSubmit()方法。
import React,{useState,useEffect} from 'react';
import {Link} from 'react-router-dom';
const Login=()=>{
const [loginDetails,setLoginDetails]=useState({
email:'',
password:''
})
const handleChange=(e)=>{
setLoginDetails({...loginDetails,[e.target.id]:e.target.value})
}
const handleSubmit=(e)=>{
e.preventDefault();
console.log(loginDetails)
}
return(
<>
<div className="container">
<div className="row">
<div className="col-4 mx-auto mt-5">
<div className="row my-3 justify-content-center">
<h4>Login</h4>
</div>
<div className="card">
<div className="card-body">
<form onChange={handleChange} onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email address</label>
<input type="email" className="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" className="form-control" id="password" placeholder="Password" />
</div>
<div className="row justify-content-center my-3">
<Link to="/signup">Don't have an account? Signup</Link>
</div>
<div className="row justify-content-center">
<button type="submit" className="btn btn- primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default Login;
类似地,创建Signup组件,如下所示:
import React,{useState,useContext} from 'react';
import {Link} from 'react-router-dom';
const Signup=()=>{
const [SignupDetails,setSignupDetails]=useState({
email:'',
password:'',
})
const handleChange=(e)=>{
setSignupDetails({...SignupDetails,[e.target.id]:e.target.value})
}
const handleSubmit=(e)=>{
e.preventDefault();
console.log(SignupDetails)
}
return(
<>
<div className="container">
<div className="row">
<div className="col-4 mx-auto mt-5">
<div className="row my-3 justify-content-center">
<h4>Signup</h4>
</div>
<div className="card">
<div className="card-body">
<form onChange={handleChange} onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email address</label>
<input type="email" className="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" className="form-control" id="password" placeholder="Password" />
</div>
<div className="row justify-content-center my-3">
<Link to="/login">Already have an account? Login</Link>
</div>
<div className="row justify-content-center">
<button type="submit" className="btn btn-primary">Sign up</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default Signup;
在主页中,该组件显示经过身份验证的用户的电子邮件以及一个注销按钮。
import React fom 'react';
const Home=()=>{
return(
<>
<div className="container">
<div className="row">
<div className="col-4 mx-auto mt-5">
<div className="card" style={{width: '18rem'}}>
<div className="card-body">
<h6 className="card-subtitle mb-2 text-muted">Email</h6>
<button className="btn btn-info">Logout</button>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default Home;
创建全局上下文存储
上下文存储与您的localStorage通信,并充当您应用的全局状态。使用其提供程序作为子项呈现的组件可以访问此全局状态。
首先,使用createContext()钩子创建一个上下文并设置初始状态。然后创建一个提供程序,这是一个函数组件,充当使用全局状态的所有组件的包装器。接下来,从useReducer()钩子中提取状态和调度,并将您的 Reducer 作为第一个参数传递,将您的初始状态initState作为第二个参数传递。最后,检查您的localStorage。如果它为空,则将initState分配给您的全局状态;否则,将现有数据推送到它。
import React, {createContext, useEffect, useReducer} from 'react';
import {AuthReducer} from '../reducers/AuthReducer';
export const UserContext=createContext();
const initState={
isSignedUp:false,
isAuthenticated:false,
currentUser:null
}
export const UserContextProvider=(props)=>{
const [state, dispatch] = useReducer(AuthReducer, initState,()=>{
const data=localStorage.getItem('state');
return data?JSON.parse(data):initState
});
useEffect(()=>{
localStorage.setItem('state',JSON.stringify(state));
},[state])
return(
<UserContext.Provider value={{state,dispatch}}>
{props.children}
</UserContext.Provider>
)
}
将您的组件包装在UserContextProvider里面。
...
<UserContextProvider>
<Route exact path="/" component={Home}/>
<Route exact path="/signup" component={Signup}/>
<Route exact path="/login" component={Login}/>
</UserContextProvider>
...
创建 Reducer
Reducer 内部的操作与 Redux 中的操作类似。您可以在此处创建案例来确定应用流程。例如,在提交注册表单时,您需要触发SIGNUP操作以将新创建的用户添加到数据库(此处为浏览器的localStorage)。在LOGIN操作中,写下验证用户的逻辑。最后,在LOGOUT操作中,使用户的会话过期。您的 Reducer 根据您决定在何时渲染哪个组件来更新全局状态。
<code class="langua
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~