Javascript

React18项目实战:从零开始的完整指南

本文主要是介绍React18项目实战:从零开始的完整指南,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概述

本文详细介绍了从零开始使用React 18进行项目开发的全过程,包括环境搭建、组件创建、状态管理、路由配置以及API数据请求等内容。同时,还涵盖了项目的打包部署和性能优化技巧,帮助你全面掌握React 18项目实战。React 18项目实战涉及的知识点全面且实用,适合初学者和有一定经验的开发者参考。

React 18 项目实战:从零开始的完整指南
React 18基础入门

介绍React及其最新版本React 18

React 是由 Facebook 开发并维护的一个用于构建用户界面的 JavaScript 库。React 致力于提高开发效率与用户体验,通过声明式设计高效地构建用户界面,遵循“渐进式增强”的设计思路,使得开发者可以逐步提升应用的复杂度和性能。最新的 React 版本 React 18 带来了许多新特性,比如支持并发模式,改进了SSR和代码分割等,使得React在性能和易用性上得到了进一步的提升。

安装Node.js和npm

在开始使用React之前,需要先安装Node.js和npm(Node Package Manager)。Node.js 是一个开源的、跨平台的 JavaScript 运行环境,可以运行在服务端。npm 是 Node.js 的包管理器,可以通过 npm 安装和管理 React 和其他相关库。

  1. 访问 Node.js 官方网站 下载最新版本的 Node.js。
  2. 安装Node.js时,会自动安装npm。

检查安装是否成功:

node -v
npm -v

确保 Node.js 和 npm 已经正确安装。

使用Create React App快速搭建项目环境

Create React App 是一个官方推荐的脚手架工具,用于快速搭建 React 项目。它提供了开箱即用的设置,包括构建工具、测试框架和开发服务器等功能。

  1. 打开终端(命令行工具)。
  2. 使用 npm 安装 Create React App 的命令行工具:
npm install -g create-react-app
  1. 使用 Create React App 创建一个新的 React 项目:
npx create-react-app my-app

这会创建一个名为 my-app 的 React 项目,并自动安装必要的依赖。

  1. 进入项目目录:
cd my-app
  1. 启动开发服务器:
npm start

此时,浏览器会自动打开 http://localhost:3000,展示新的 React 项目。

创建简单的React组件

在 React 中,组件是构建用户界面的基本单位。每个组件通常包含一个输入(props)和一个输出(描述 UI 的 HTML 标签)。

  1. src/components 目录下创建一个名为 HelloWorld.js 的新文件。
  2. 编写一个简单的函数组件:
// src/components/HelloWorld.js
import React from 'react';

function HelloWorld() {
  return <h1>Hello, World!</h1>;
}

export default HelloWorld;
  1. App.js 文件中引入并使用该组件:
// src/App.js
import React from 'react';
import HelloWorld from './components/HelloWorld';

function App() {
  return (
    <div className="App">
      <HelloWorld />
    </div>
  );
}

export default App;

此时,浏览器中的应用会显示 "Hello, World!"。

React组件开发

组件的分类:函数组件和类组件

在 React 中,有两种主要的组件类型:函数组件和类组件。

函数组件

函数组件是最简单的组件类型,它们是接收 props 作为输入并返回一个 UI 组件的函数。

// src/components/FuncComponent.js
import React from 'react';

function FuncComponent(props) {
  return <h1>Hello, {props.name}!</h1>;
}

export default FuncComponent;

类组件

类组件是基于 ES6 类语法的组件,它不仅接收 props 作为输入,还可以包含内部状态和生命周期方法。

// src/components/ClassComponent.js
import React, { Component } from 'react';

class ClassComponent extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default ClassComponent;

组件的属性(Props)和状态(State)

属性(Props)

属性是父组件传递给子组件的数据。子组件通过 props 接收数据,使用这些数据来渲染 UI。

// src/App.js
import React from 'react';
import HelloWorld from './components/HelloWorld';

function App() {
  return (
    <div className="App">
      <HelloWorld name="Alice" />
      <HelloWorld name="Bob" />
    </div>
  );
}

export default App;

状态(State)

状态是组件内部的数据,用于控制组件的行为。状态应该被视为不可变的,只能通过 setState 来更新。

// src/components/Counter.js
import React, { Component } from 'react';

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

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

export default Counter;

使用Hooks简化组件开发

React Hooks 是 React 16.8 引入的新特性,允许我们在不编写类的情况下使用状态和其他 React 特性。主要的 Hooks 包括 useStateuseEffectuseContext 等。

使用 useState

useState 允许我们在函数组件中使用状态。

// src/components/UseStateCounter.js
import React, { useState } from 'react';

function UseStateCounter() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

export default UseStateCounter;

使用 useEffect

useEffect 允许我们执行副作用操作,如订阅、设置定时器、发送网络请求等。

// src/components/UseEffectExample.js
import React, { useState, useEffect } from 'react';

function UseEffectExample() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default UseEffectExample;
状态管理和数据流

父子组件间的状态传递

在 React 中,可以使用 props 将状态从父组件传递给子组件。

// src/components/ParentComponent.js
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
  const [message, setMessage] = useState('Hello from Parent');

  return (
    <ChildComponent message={message} />
  );
}

export default ParentComponent;
// src/components/ChildComponent.js
import React from 'react';

function ChildComponent(props) {
  return <h1>{props.message}</h1>;
}

export default ChildComponent;

使用Context API管理全局状态

Context API 用于在组件树中传递数据。它避免了在组件树中进行 prop drilling(即层层传递 props)。

// src/Context.js
import React, { createContext, useContext, useState } from 'react';

const MyContext = createContext();

function MyProvider({ children }) {
  const [theme, setTheme] = useState('light');

  return (
    <MyContext.Provider value={{ theme, setTheme }}>
      {children}
    </MyContext.Provider>
  );
}

export const useMyContext = () => useContext(MyContext);
export { MyProvider };
// src/App.js
import React from 'react';
import MyProvider from './Context';
import ChildComponent from './ChildComponent';

function App() {
  return (
    <MyProvider>
      <ChildComponent />
    </MyProvider>
  );
}

export default App;
// src/components/ChildComponent.js
import React from 'react';
import { useMyContext } from '../Context';

function ChildComponent() {
  const { theme, setTheme } = useMyContext();

  return (
    <div>
      <h1>{theme}</h1>
      <button onClick={() => setTheme('dark')}>Toggle Theme</button>
    </div>
  );
}

export default ChildComponent;

状态管理库Redux的基本使用

Redux 是一个用于 JavaScript 应用的状态管理库,它通过单一的 store 来管理应用的所有状态。

  1. 安装 Redux 相关库:
npm install redux react-redux
  1. 创建 Redux Store:
// src/store.js
import { createStore } from 'redux';

const initialState = {
  counter: 0,
};

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { counter: state.counter + 1 };
    case 'DECREMENT':
      return { counter: state.counter - 1 };
    default:
      return state;
  }
};

const store = createStore(rootReducer);

export default store;
  1. 创建 Redux 连接组件:
// src/components/Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from '../actions';

function Counter() {
  const counter = useSelector((state) => state.counter);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Count: {counter}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
}

export default Counter;
  1. App.js 中使用 Provider
// src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './components/Counter';

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

export default App;
路由与导航

使用React Router进行页面路由配置

React Router 是一个用于 React 应用的路由库。它允许你定义应用的不同页面,并使用这些页面进行导航。

  1. 安装 React Router:
npm install react-router-dom
  1. 配置路由:
// src/App.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/contact">Contact</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
      </div>
    </Router>
  );
}

export default App;
  1. 创建页面组件:
// src/components/Home.js
import React from 'react';

function Home() {
  return <h2>Home Page</h2>;
}

export default Home;
// src/components/About.js
import React from 'react';

function About() {
  return <h2>About Page</h2>;
}

export default About;
// src/components/Contact.js
import React from 'react';

function Contact() {
  return <h2>Contact Page</h2>;
}

export default Contact;

实现单页面应用中的多页面跳转

在 React Router 中,通过不同的路径配置可以实现页面的跳转。

// src/App.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link, Redirect } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
import NotFound from './components/NotFound';

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/contact">Contact</Link>
            </li>
            <li>
              <Link to="/notfound">Not Found</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
          <Route path="/notfound" component={NotFound} />
          <Redirect to="/" />
        </Switch>
      </div>
    </Router>
  );
}

export default App;

路由参数传递与使用

React Router 支持传递和使用路由参数。

// src/App.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link, useParams } from 'react-router-dom';
import Home from './components/Home';
import User from './components/User';

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/user/1">User 1</Link>
            </li>
            <li>
              <Link to="/user/2">User 2</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/user/:id" component={User} />
        </Switch>
      </div>
    </Router>
  );
}

export default App;
// src/components/User.js
import React from 'react';
import { useParams } from 'react-router-dom';

function User() {
  const { id } = useParams();

  return <h2>User: {id}</h2>;
}

export default User;
请求API数据

使用fetch和axios发送HTTP请求

fetch 是浏览器内置的用于发送 HTTP 请求的方法,axios 是一个常用的 HTTP 客户端库。

使用 fetch

// src/components/FetchData.js
import React, { useEffect, useState } from 'react';

function FetchData() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then((response) => response.json())
      .then((data) => setData(data))
      .catch((error) => console.error(error));
  }, []);

  return (
    <div>
      {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : 'Loading...'}
    </div>
  );
}

export default FetchData;

使用 axios

// src/components/AxiosData.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';

function AxiosData() {
  const [data, setData] = useState(null);

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/todos/1')
      .then((response) => setData(response.data))
      .catch((error) => console.error(error));
  }, []);

  return (
    <div>
      {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : 'Loading...'}
    </div>
  );
}

export default AxiosData;

处理异步数据和错误处理

在处理异步数据时,需要关注请求的响应和错误处理。

// src/components/FetchDataWithError.js
import React, { useEffect, useState } from 'react';

function FetchDataWithError() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then((response) => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then((data) => setData(data))
      .catch((error) => {
        setError(error);
        console.error('There was an error!', error);
      });
  }, []);

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  if (!data) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export default FetchDataWithError;

实现数据的实时更新

使用 useEffectsetState,可以实现数据的实时更新。

// src/components/RealtimeData.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';

function RealtimeData() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const intervalId = setInterval(() => {
      axios.get('https://jsonplaceholder.typicode.com/todos/1')
        .then((response) => setData(response.data))
        .catch((error) => console.error(error));
    }, 5000);

    return () => clearInterval(intervalId);
  }, []);

  if (!data) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export default RealtimeData;
项目部署与优化

项目打包与部署

使用 npm run build 命令打包项目,生成的 build 目录下的文件可以直接部署到生产环境。

npm run build

生成的文件可以部署到任何静态文件服务器,如 AWS S3、Netlify、Vercel 等。

使用AWS S3部署

aws s3 cp build/ s3://your-bucket-name --recursive

使用Netlify部署

netlify deploy --dir=build

使用Vercel部署

vercel --prod

性能优化技巧

  1. 代码分割:使用 import() 语法进行动态导入,按需加载模块。
import("./myComponent").then(module => {
  const MyComponent = module.default;
  render(<MyComponent />);
});
  1. 懒加载:使用 React Router 的 lazy 函数实现组件的懒加载。
import React from 'react';

const MyComponent = React.lazy(() => import('./MyComponent'));

function App() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <MyComponent />
    </React.Suspense>
  );
}
  1. SSR(服务器端渲染):使用 Next.js 或 Gatsby 等框架实现服务器端渲染,提升首屏加载速度。
import { useRouter } from 'next/router';
import React from 'react';

function MyComponent() {
  const router = useRouter();
  const { id } = router.query;
  // fetch data using id
  return <div>Component with {id}</div>;
}

export async function getServerSideProps(context) {
  const { id } = context.query;
  // fetch data using id
  return { props: { id } };
}

export default MyComponent;
  1. 缓存:利用浏览器缓存、服务端缓存等技术减少不必要的请求。
res.setHeader('Cache-Control', 's-maxage=31536000, stale-while-revalidate=2592000');
  1. 压缩:通过压缩静态资源文件,减小文件体积,加快加载速度。
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[hash].[ext]',
              outputPath: 'images/',
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
};

使用环境变量

环境变量可以帮助你在开发和生产环境中使用不同的配置。

  1. 创建 .env 文件:
# .env
REACT_APP_API_URL=https://api.example.com
REACT_APP_ENV=development
  1. 在代码中使用环境变量:
import React from 'react';
import axios from 'axios';

const apiBaseUrl = process.env.REACT_APP_API_URL;

function MyComponent() {
  return <div>API URL: {apiBaseUrl}</div>;
}

export default MyComponent;

以上内容详细介绍了从零开始使用 React 18 创建一个完整项目的整个过程,包括安装环境、创建组件、状态管理、路由配置、数据请求、项目部署与优化等。希望对你有所帮助。

这篇关于React18项目实战:从零开始的完整指南的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!