Search Posts

React的web应用开发从0到1:创建、路由、状态管理、发布


创建React应用:

使用 npm 创建 React Web 应用的命令如下:

  1. 首先,您需要安装 Node.js 和 npm。如果您还没有安装 Node.js 和 npm,请先安装它们。
  2. 打开命令行工具,并进入您想要创建 React Web 应用的目录。
  3. 在命令行中运行以下命令,使用 create-react-app 工具创建 React Web 应用:
    npx create-react-app my-app

    在上面的命令中,`my-app` 是您要创建的应用程序的名称。您可以将其替换为您自己的应用程序名称。

  4. create-react-app 工具将会自动创建一个新的 React Web 应用,并安装所需的依赖包。创建完成后,您可以进入新创建的应用程序目录:
    cd my-app
  5. 在应用程序目录中,您可以使用以下命令启动开发服务器:
    npm start

运行上述命令后,开发服务器将会启动,并在浏览器中打开应用程序。您可以在开发服务器启动后,通过访问 `http://localhost:3000` 来访问应用程序。

现在,您已经成功地创建了一个新的 React Web 应用,并启动了开发服务器。您可以开始编写您的应用程序代码,并使用 `npm start` 命令来预览您的应用程序。


React web应用的目录文件结构

在使用命令创建react web应用后,看到的目录和文件结构是这样的:

React Web 应用的目录文件结构可以根据具体需求进行调整,但通常包含以下文件和目录:

  • src: 存放应用程序的源代码。
    • components: 存放应用程序的组件。
    • pages: 存放应用程序的页面组件。
    • assets: 存放应用程序所需的静态资源,例如图片、字体等。
    • styles: 存放应用程序的样式文件,例如 CSS、Sass、Less 等。
    • utils: 存放应用程序的工具函数和帮助函数。
    • services: 存放应用程序的服务,例如 API 请求等。
    • constants: 存放应用程序的常量,例如枚举值、配置项等。
    • App.js: 应用程序的主组件。
    • index.js: 应用程序的入口文件。
  • public: 存放应用程序所需的静态文件,例如 HTML、favicon.ico 等。
  • node_modules: 存放应用程序的依赖包。
  • package.json: 应用程序的配置文件,包括依赖包、启动脚本等信息。
  • README.md: 应用程序的说明文档。通常情况下,React Web 应用的目录结构遵循单一职责原则和分层架构原则,将不同类型的文件放置在对应的目录中,以便于代码的组织和维护。例如,组件应该放置在 components 目录中,页面组件应该放置在 pages 目录中,静态资源应该放置在 assets 目录中等等。

    除了上述目录和文件之外,您还可以根据具体需求添加其他的目录和文件。例如,如果您的应用程序需要国际化支持,您可以添加一个 locales 目录,用于存放不同语言的翻译文件。如果您的应用程序需要使用 Redux 来管理状态,您可以添加一个 redux 目录,用于存放 Redux 相关的文件。


React 中的组件如何传入参数

React的页面通过组件实现页面部件的灵活组合。组件的动态数据通过组件初始化时的参数设定。例如,假设您的 About 组件接收两个参数 `company_info` 和 `address`,您可以在 App 组件(src/App.jsx 文件)中引入 About 组件(src/About.jsx文件),并将这两个参数传递给 About 组件。下面是一个示例代码:

App组件代码文件src/App.jsx:

import React from 'react';
import About from './About';

function App() {
const companyInfo = { name: 'ABC Company', industry: 'Technology' };
const address = { street: '123 Main St', city: 'San Francisco', state: 'CA', zip: '94111' };

return (
<div>
<About company_info={companyInfo} address={address} />
</div>
);
}

export default App;

在上面的代码中,我们首先引入 About 组件,并定义了 `companyInfo` 和 `address` 两个参数的值。然后,我们在 App 组件中使用 About 组件,并将这两个参数传递给 About 组件,其中 `company_info` 对应 `companyInfo` 参数,`address` 对应 `address` 参数。

关于 About 组件的定义,您需要在 About.js 文件中编写代码。在 About.js 文件中,您可以通过 `props` 对象来获取传递给 About 组件的参数,例如:

About组件代码文件src/About.jsx:

import React from 'react';

function About(props) {
  const companyInfo = props.company_info;
  const address = props.address;

  return (
    <div>
    <h2>About Us</h2>
    <p>Company Name: {companyInfo.name}</p>
    <p>Industry: {companyInfo.industry}</p>
    <p>Address: {address.street}, {address.city}, {address.state} {address.zip}</p>
    </div>
  );
}

export default About

在上面的代码中,我们首先通过 `props` 对象获取了传递给 About 组件的 `company_info` 和 `address` 参数。然后,我们在组件中使用这些参数来渲染 UI。例如,我们使用 `companyInfo.name` 来显示公司名称,使用 `address.street`、`address.city`、`address.state` 和 `address.zip` 来显示地址信息。

React 中的页面跳转(路由)的实现原理:

React 中的路由通常使用第三方库来实现,最流行的路由库是 react-router。使用 react-router 可以帮助您在 React 应用程序中实现路由功能,使得用户能够在不同的 URL 之间切换,同时保持单页应用程序(SPA)的优势。

下面是一个使用 react-router 实现路由功能的示例:

  1. 首先,您需要安装 react-router-dom 包。您可以使用 npm 或 yarn 安装该包:

    npm install react-router-dom
    # 或者
    yarn add react-router-dom
  2. 在您的 React 应用程序中,您需要导入 BrowserRouter 和 Route 组件,以便实现路由功能。例如:

    import { BrowserRouter, Route } from 'react-router-dom';
    
    function App() {
      return (
        <BrowserRouter>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </BrowserRouter>
      );
    }

    在上面的代码中,我们使用 BrowserRouter 组件创建了一个路由器,并在其中定义了三个路由规则。其中,exact 属性表示该路由规则只匹配精确的 URL,而不是 URL 的子路径。例如,exact path="/" 只匹配根路径,而不匹配任何子路径。component 属性指定了该路由规则所对应的组件。

  3. 在您的组件中,您可以使用 Link 组件来创建一个链接,以便用户能够点击该链接并切换到对应的 URL。

    import { Link } from 'react-router-dom';
    
    function Navbar() {
      return (
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/contact">Contact</Link>
            </li>
          </ul>
        </nav>
      );
    }

在上面的代码中,我们使用 `Link` 组件创建了三个链接,分别对应于不同的 URL。用户可以点击这些链接来切换到对应的 URL。

以上是一个基本的使用 `reactrouter` 实现路由功能的示例。在实际应用中,您还可以使用 `Switch` 组件、`Redirect` 组件、嵌套路由等功能来实现更复杂的路由需求。


React 应用的状态管理逻辑:

在 React 中,变量状态是通过组件的状态(State)来管理的。组件的状态是一个可以被改变的 JavaScript 对象,它包含了组件的数据,并且可以在组件的生命周期中被修改。

组件的状态可以通过 this.state 属性来访问,以及通过 this.setState() 方法来更新。当 this.setState() 方法被调用时,React 会自动重新渲染组件,并根据新的状态更新组件的 DOM。

下面是一个示例:

import React from 'react';

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.handleClick()}>
          Click me
        </button>
      </div>
    );
  }
}

在上面的代码中,Example 组件的状态包含了一个名为 count 的变量。当用户点击按钮时,handleClick() 方法会被调用,使用 this.setState() 方法来更新 count 变量的值。在组件的 render() 方法中,this.state.count 被用来显示用户点击按钮的次数。

需要注意的是,状态只能通过 this.setState() 方法来更新。直接修改 this.state 属性的值是不会触发组件的重新渲染的。而且,由于 this.setState() 方法是异步的,所以不能直接依赖于 this.state 的值来更新状态,而应该使用回调函数来确保更新的正确性。例如:

// 不能保证更新的正确性
this.setState({ count: this.state.count + 1 });

// 应该使用回调函数确保更新的正确性
this.setState(prevState => ({ count: prevState.count + 1 }

如何回调函数来确保更新的正确性?

React 中的 setState 方法是一个异步方法,因此在对状态进行更新时,不能直接依赖于 this.state 的值来进行计算,因为此时 this.state 的值可能还没有更新。为了确保更新的正确性,可以使用 setState 方法的回调函数来进行计算。回调函数会在状态更新完成后被调用,因此可以确保更新的正确性。

下面是一个使用react回调函数 管理react状态值 的示例代码:

this.setState(
  { count: this.state.count + 1 },
  () => {
    // 在回调函数中进行计算
    console.log(`The count is now ${this.state.count}`);
  }
);

在上面的代码中,setState 方法的第二个参数是一个回调函数,在状态更新完成后会被调用。在回调函数中,可以使用更新后的状态值来进行计算。例如,上面的示例中,在回调函数中使用 this.state.count 来输出更新后的计数值。

使用回调函数的好处是可以确保状态更新完成后再进行计算,避免了状态更新的不确定性,使得代码更加稳定和可靠。

React应用打包发布:

package.json 配置文件中的辅助脚本作用说明:

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

在之前 创建 应用的时候,package.json 文件里有以上类似内容。

在 React 项目的 package.json 文件中,"scripts" 属性是一个包含了各种命令的对象,可以通过 npm run 命令来执行这些命令。下面是 "scripts" 对象中常见的几个命令及其作用:

  • "start": "react-scripts start":开始开发模式并启动开发服务器。在开发模式下,React 会自动重新编译代码,并在浏览器中实时更新显示结果。
  • "build": "react-scripts build":构建生产环境的代码。在构建过程中,React 会对代码进行压缩和优化,以提高性能和加载速度。
  • "test": "react-scripts test":运行测试。React 提供了测试工具和测试框架,可以在开发和构建过程中进行自动化测试,确保代码的质量和稳定性。
  • "eject": "react-scripts eject":将项目从 React 脚手架中“弹出”,以获得更多的配置自由度。执行该命令会将 React 脚手架的配置文件复制到项目中,并将其解除封装,以便进行更多的自定义配置。

除了常见的这些命令外,您还可以根据自己的需求添加和修改 "scripts" 对象中的命令,以便更好地管理和使用 React 项目。

如何打包发布React 应用:

运行 命令编译 代码得到 适用于生产环境的代码文件(生成在 build/ 目录下):

npm run build

运行 npm run build 命令会生成用于生产环境的代码,也就是发布版本的代码。与开发环境不同,生产环境的代码经过了优化和压缩,以提高性能和加载速度。这些优化包括删除注释、去除空格、混淆代码等操作。

通过运行 npm run build 命令,React 会使用 Webpack 工具将源代码编译成生产环境的代码,并将编译后的代码输出到 build 文件夹中。这些编译后的代码是可以直接部署到服务器上的,以便用户访问和使用。

需要注意的是,在开发阶段,我们可以使用 npm start 命令来启动开发服务器,以便进行开发和调试。npm start 命令会生成用于开发环境的代码,也就是调试版本的代码。该版本的代码通常会包含开发工具和调试信息,以便进行调试和错误定位。但是,这种代码并不适合直接部署到生产环境中,因为它没有经过优化和压缩,加载速度会比较慢,同时也存在安全风险。

进阶(原理、版本差异、使用React做移动APP开发):

React工作原理

目前我们的项目多个组件App和Message,如图components/目录下的 *.jsx 文件名的都是不同组件,下图包括About、App、Contact、Frame、Home、Link 组件。

当应用启动时,React会根据组件相应地建立Javascript数据结构,叫虚拟DOM。虚拟DOM与在浏览器显示的实际DOM是不同的,它是组件树在内存中的表示,每一个节点表示一个组件及其属性。当组件的状态或者说数据变化时,相应的虚拟DOM节点也作相应的更新反映新的状态,然后虚拟DOM再比较当前版本与之前的版本,以决定是否需要更新实际的DOM。

从技术上讲,更新DOM不是由React完成的,而是由它的同伴React DOM完成的。我们查看package.json,发现目前依赖的就是两个库:React和React DOM。

...
"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
},
...

我们来看看它们是如何一起工作的。

React代码目录结构中,src/index.jsx 会将组件绑定于 public/index.html 的root元素位置,src/index.jsx是我们的应用的入口点。查看index.jsx发现,ReactDOM负责渲染我们整个组件树,根组件 App 包含在另一个叫React.StrictMode的组件里,这个组件不用于显示,而是用于发现一些问题。

...
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

React 版本和语法差异:

一些使用React旧版本的代码 src/index.js 文件写法:

import ReactDOM from 'react-dom'
ReactDom.render(<App />, document.getElementById('root'))

则 npm start 时会有告警信息:

ReactDOM.render is no longer supported in React 18. Use createRoot instead.

修改为如下新版本代码:

import {createRoot} from 'react-dom/client';
createRoot(document.getElementById('root')).render(<App />);

再结合最新版本React项目my-app 配置文件 package.json 内容:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@mui/styles": "^5.13.2",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^5.3.4",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

其中react和react dom组件的版本都是18,

"react": "^18.2.0",
"react-dom": "^18.2.0",

且由于使用了 ReactDOM.createRoot() 这个代码,在 npm run build 打包发布的时候,不会再有告警信息。

移动APP中使用React开发页面

在手机App中,渲染画面使用的是另一个库:React Native。React没有跟具体平台绑定,它对平台是透明的,React创建的应用可以在Web、手机或桌面上使用。

React Native 和 Expo 让你可以使用 React 构建 Android、iOS 等应用程序。它们的样式和体验都和原生应用程序一样,因为它们的用户界面是真正的原生用户界面。你的 React 组件由平台提供的真实 Android 或 iOS 视图来渲染。

react 开发web应用跟 React Native 开发移动应用的本质区别是什么?

React 和 React Native 都是由 Facebook 开发的用于构建用户界面的 JavaScript 库。它们的本质区别在于,React 用于构建 Web 应用程序,而 React Native 用于构建原生移动应用程序。

具体来说,React 通过虚拟 DOM 来管理 UI,使用 HTML 和 CSS 来定义用户界面。而 React Native 则使用类似 HTML 和 CSS 的 JSX 语法来定义 UI,但是它最终会被转换为原生组件,例如 iOS 中的 UIView 和 Android 中的 View。

由于 React Native 使用原生组件来构建用户界面,因此它可以直接调用操作系统的 API,实现更高效的渲染和更好的性能。同时,React Native 支持使用 JavaScript 来编写业务逻辑和控制流程,使得开发人员可以使用相同的技术栈来构建 iOS 和 Android 应用程序,减少了开发成本和维护难度。

相比之下,React 更适合构建 Web 应用程序,它可以在浏览器中直接渲染用户界面。React 支持使用 React Router 来管理路由,使用 Redux 管理状态,使用 CSS-in-JS 等技术来实现更灵活和可复用的组件。

总之,React 和 React Native 都是用于构建用户界面的 JavaScript 库,但它们的本质区别在于目标平台不同,React 用于构建 Web 应用程序,而 React Native 用于构建原生移动应用程序。

加好友请备注:chinaoss
您可以在微信公众号联系我们
我们将24小时内回复。
取消