如何使用 React 从应用程序中的任何位置获取组件

发布日期:2026-07-15 11:10:03   来源 : 杭州电子商务研究院    浏览量 :10
杭州电子商务研究院 发布日期:2026-07-15 11:10:03  
10

介绍

React 中的 UI 组件可以看作是一组 HTML 元素。Web 开发人员经常想知道是否可以将整个组件视为 DOM 元素并使用idclassName引用它。当然,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
    

创建路线

该应用程序包含三个不同页面的三个路由:LoginSignupHomeHome组件是用户成功登录后看到的内容。请考虑以下代码,它设置了应用程序的路由并一次渲染一个路由:

      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
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据