一周掌握React框架(一)

134 阅读4分钟
npx create-react-app react-basic
  1. npx 是包管理器,用于执行 npm 包中的可执行文件。它允许在不全局安装包的情况下直接运行 npm 包中的命令。

  2. create-react-app 是一个 React 应用程序的脚手架工具,它可以帮助你快速搭建起一个基于 React 的开发环境,包括构建、调试、测试等。

  3. react-basic 是你要创建的 React 项目的名称。

// index.js
// 整个项目的入口 等于vue中的 main.ts
import React from "react";
import ReactDOM from "react-dom";

// 导入根组件
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);

// App.js 根组件
function App() {
  return (
    <div className="App">
      this is App
    </div>
  );
}

export default App;

什么是JSX? JSX 是 JavaScript 和 XML 的结合体,是 JavaScript 的语法扩展,需要通过解析工具解析,如 Babel。

JSX 使用 JavaScript 表达式:

  1. 引号传递字符串。
  2. 使用 JavaScript 变量。
  3. 函数或方法调用。
  4. 使用 JavaScript 对象。
let count = 100;

const AddCount = () => {
  count++;
};

// 根组件
function App() {
  return (
    <div className="App">
      this is App
      {"hello"}
      {count}
      {AddCount()}
      <div style={{ color: "red" }}>对象形式</div>
    </div>
  );
}

export default App;

列表遍历(对比 v-for):

const list = [
  {
    id: 1,
    name: "Vue",
  },
  {
    id: 2,
    name: "React",
  },
  {
    id: 3,
    name: "Jquery",
  },
];

// 根组件
function App() {
  return (
    <div className="App">
      this is App
      <ul>
        {list.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

条件渲染(对比 v-if):

// 那 v-show 怎么处理嘞?
const isLogin = true;

// 根组件
function App() {
  return (
    <div className="App">
      {isLogin && <div>已登录</div>}
      {isLogin ? <div>三元已登录</div> : <div>三元未登录</div>}
    </div>
  );
}

事件绑定:(类比为 @click)

// 根组件
function App() {
  const handleClick = () => {
    console.log("被点击了");
  };
  return (
    <div className="App">
      <button onClick={handleClick}>点我测试</button>
    </div>
  );
}
// 使用箭头函数中转,可以传递自定义的参数,还可以同时获取点击的默认参数。Vue 中也是,但 Vue 中可以 $event 来获取默认参数。
function App() {
  const handleClick = (e, name) => {
    console.log("被点击了", e, name);
  };
  return (
    <div className="App">
      <button onClick={(e) => handleClick(e, "name")}>点我测试</button>
    </div>
  );
}

export default App;

组件: React 组件必须要首字母大写。组件当成标签用就可以了。

// 定义
function Button() {
  return (
    <>
      <div>我是 button 组件</div>
    </>
  );
}

// 根组件
function App() {
  return (
    <div className="App">
      <Button />
    </div>
  );
}

useState 使用: 是一个 React Hook 函数,添加响应式变量,相当于 Ref,Reactive。

useState 传入初始值,返回一个数组,第一个值是状态变量,第二个是修改方法。

import { useState } from "react";

function App() {
  const [count, setCount] = useState(100);

  return (
    <div className="App">
      <Button />
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        {count}
      </button>
    </div>
  );
}

useState 的规则: 需要注意的点。

  • 状态不可变,需要替换状态,不可以修改。修改不会引发视图更新。
  • 对象类型的状态变量,始终传递全新的对象来修改。有点麻烦,后面用其他的库来处理这个。
import { useState } from "react";

// 根组件
function App() {
  const [obj, setObj] = useState({ name: "离火塔" });

  return (
    <div className="App">
      <button
        onClick={() => {
          setObj({ ...obj, name: "嘻嘻" });
        }}
      >
        {obj.name}
      </button>
    </div>
  );
}

React 样式写法:

// app.js
import "./index.css";

function App() {
  return (
    <div className="App">
      <div style={{ color: "red", fontSize: "30px" }}>YYDS</div>
      <div className="my-div">YYDS</div>
    </div>
  );
}
.my-div {
  background-color: aqua;
}

Tips:

  1. 注意使用 React 时,如果遇到状态变量需要排序时,请使用 lodash 的排序方法。原生的 sort 会改变原数组。
  2. classnames 优化类名控制。是一个 JavaScript 库,方便使用的。跟 Vue 写法很像。
className={classNames('nav-item', { active: type === item.type })}

受控表单状态

受控表单状态类似于 Vue 中的 v-model 双向绑定。

import { useState } from "react"

function App() {
  const [value, setValue] = useState("")

  return (
    <div className="App">
      <input value={value} onChange={(e) => setValue(e.target.value)} type="text" />
    </div>
  )
}

React 获取 DOM 元素

React 获取 DOM 元素需要使用 useRef Hook 函数。

import { useRef } from "react"

function App() {
  const inputRef = useRef(null)

  const showDom = () => {
    console.dir(inputRef.current)
  }

  return (
    <div className="App">
      <input type="text" ref={inputRef} />
      <button onClick={showDom}>点我显示 DOM</button>
    </div>
  )
}

组件通信

1. 父子组件通信

父子组件通信与 Vue 的 props 类似。

function Son(props) {
  console.log(props)
  return <div>{props.name}</div>
}

function App() {
  const name = "this is my name"

  return (
    <div className="App">
      <Son name={name} hello="uuuu" />
    </div>
  )
}

tips : 特殊 Prop - children

children 相当于 Vue 的默认插槽。

function Son(props) {
  return (
    <div>
      this is Son
      <div>{props.children}</div>
    </div>
  )
}

function App() {
  return (
    <div className="App">
      <Son>
        <span>this is children</span>
      </Son>
    </div>
  )
}

父组件传递函数给子组件:

父组件传递一个函数给子组件,子组件调用该函数可修改父组件参数。

2. 使用状态提升实现兄弟组件通信

使用状态提升实现兄弟组件通信,父组件传递状态给子组件,子组件传递修改状态的函数给兄弟组件。

3. 使用 Context 机制实现跨层组件通信

使用 createContext 创建上下文对象,在顶层组件中通过 Provider 提供数据,在需要接收的组件处使用 useContext 获取消费数据。

import { createContext, useContext } from "react"

const MsgContent = createContext()

function ACom(props) {
  return (
    <div>
      this is ACom
      <div>
        <BCom></BCom>
      </div>
    </div>
  )
}

function BCom(props) {
  const getMsg = useContext(MsgContent)
  return <div>{getMsg}</div>
}

function App() {
  const msg = "this App msg"

  return (
    <div className="App">
      <MsgContent.Provider value={msg}>
        <ACom></ACom>
      </MsgContent.Provider>
    </div>
  )
}

useEffect Hook 介绍

useEffect 用于处理组件的副作用,比如发送 Ajax 请求、更改 DOM 等。可根据传递的第二个参数来控制 useEffect 的执行时机。

useEffect(() => {
  // Effect
}, [])
  • 空数组作为第二个参数:只在组件初始渲染时执行一次。
  • 不传第二个参数:组件初始渲染和每次更新都会执行。
  • 特定依赖项作为第二个参数:组件初始化和特定依赖项变化时执行。