React笔记(二)

2024 年 5 月 3 日 星期五(已编辑)
/
4
摘要
这份文档主要介绍了在React应用中使用的一些重要技术和工具,包括受控表单绑定、React中获取DOM、随机uuid的生成、时间格式化day.js、组件通信的不同方式、useEffect的使用、自定义Hook函数、React Hooks使用规则、模拟接口工具json-server、Axios的使用等内容。同时也提供了使用Fetch API和Axios处理HTTP请求的简单示例代码。
这篇文章上次修改于 2024 年 5 月 7 日 星期二,可能部分内容已经不适用,如有疑问可询问作者。

阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。

1.受控表单绑定

概念:使用React组件的状态(useState)控制表单状态

//1.准备一个React状态值
  const [value,setValue] = useState('')
//2.通过value属性绑定状态,通过onChange属性绑定状态同步的函数
  <input
    type="text"
    value={value}
    onChange={(e) => setValue(e.target.value)}
  >

2.React中获取DOM

在组件中获取/操作DOM,需要使用useRef钩子函数

//1.使用useRef创建ref对象,并与JSX绑定
const inputRef = useRef(null)
<input type='text' ref={inputRef} />
//2.在DOM可用时,通过inputRef.current拿到DOM对象
console.log(inputRef.current)

3.随机uuid

利用uuid.js随机生成唯一id

//1.安装
npm install uuid
//2.导包
import {v4 as uuid} from 'uuid'
//3.调用
uuid()

4.时间格式化day.js

利用day.js插件规范时间格式

//1.安装
npm install dayjs
//2.导包
import dayjs from 'dayjs'
//3.调用
dayjs.(new Date()).format('MM-DD HH:mm')

5.组件通信

组件之间的数据传递,根据组件嵌套关系的不同,有不同的通信方式

5.1 父传子

//1.父组件传递数据--在子组件标签上绑定属性
/*App.js*/
import Son from './son';
const sonName = 'son';
<Son name={sonName}/>

//2.子组件接收数据--子组件通过porps参数接收数据
/*Son.js*/
function Son(props) {
    return (
        <div>{props.name}</div>
    )
};

export default Son;

// props
1.props可以传递任意数据,如数字,字符串,布尔值,数组,对象,函数,JSX等
2.props是只读对象,子组件只能读取props里面的数据而不能修改,只有父组件可以进行修改

//特殊的porp children--父组件将内容嵌套在子组件中时,子组件会自动把嵌套内容通过children的prop属性来接收
<Son>
    <span>this is span</span>
</Son>

5.2 子传父

核心思路:在子组件里面调用父组件里面的函数并传入参数

//1.父组件内声明触发函数并传给子组件
const getMsg = (msg) =>{
    console.log(msg);
  }
<Son onGetSonMsg={getMsg}/>

//2.子组件内绑定传入的触发函数
function Son({onGetSonMsg}) {
    const sonMsg = 'hello world'
    return (
        <div>
            <button onClick={()=>onGetSonMsg(sonMsg)}>senMsg</button>
        </div>
    )
};

5.3 兄弟通信

借助“状态提升”机制,通过父组件来进行兄弟组件之间的数据传递

先子传父,再父传子

5.4 使用Context机制跨层组件通信

//例如App包含A,A包含B,现在要让App和B通信
//1.使用creatContext方法创建一个上下文对象Ctx、
const MsgContext = creayeContext()

//2.在顶层组件(App)中通过 Ctx.Provider 组件提供消费数据
const msg = 'this is app msg'
<MsgContext.Provider value={msg}>
      this is app
      <A />
<MsgContext.Provider>
    
//3.在底层组件(B)中通过useContext钩子函数来消费数据 
const msg = useContext(MsgContext)

6.useEffect

useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是渲染本身引起的操作,比如发送AJAX请求,更改DOM等

语法:
useEffect(() => { }, [])
//参数1是一个函数,可以把它成为副作用函数,在函数内部可以放置要执行的操作
//参数2是一个数组(可选),在数组里面放置依赖项,不同依赖项会影响第一个函数的执行,当是一个空数组的时候,副作用函数在组件渲染完毕只会执行一次
  const URL = 'https://v1.hitokoto.cn/'
  useEffect(() => {
    //ajax
    async function getList(){
      const res = await fetch(URL)
      const list = await res.json();
      console.log(list.hitokoto)
    }
    getList()
  })

//useEffect依赖项参数说明
useEffect副作用函数的执行时机存在多种情况,根据传入依赖项的不同,有不同的执行表现
没有依赖项-----------组件初始渲染+组件更新时候执行(全局更新)
空数组依赖-----------只在初始渲染时执行一次
添加特定的依赖项------组件初始渲染+特性依赖变化时候执行(局部更新)

//清除副作用
在useEffect中编写的由渲染本身引起的对接组件外部的操作,社区也经常把它叫副作用操作,比如在useEffect中开启了一个定时器,我们想在组件卸载时候把这个定时器再清理掉,这个过程叫做清理副作用
useEffect(() => {
    //实现副作用操作
    return() => {
        //清除副作用逻辑
    }
},[]);

7.自定义Hook函数

自定义Hook函数是以use开头的函数,通过自定义Hook函数可以实现逻辑的封装和复用

//核心思路:把可复用部分抽象出去

function useToggle () {
    const [value,setValue] = useState(true)
    const toggle = () => setValue(!value)
    
    return {
        value,
        toggle
    }
}
...
const {value,toggle} = useToggle()
...

8.React Hooks使用规则

1.所有以use开头的hook函数只能在组件中或者其他自定义函数中使用

2.只能在组件顶层中调用,不能嵌套在if,for等其他函数

9.模拟接口工具——json-server

json-server是一个快速以.json文件作为数据源模拟接口服务的工具

//1.安装
npm install json-server
//2.创建一个json文件模拟数据库
db.json
//3.开启服务
json-server --watch db.json

10.axios

// 导入 Axios
import axios from 'axios';

// 发起 GET 请求
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('错误:', error);
  });

// 发起 POST 请求
axios.post('https://api.example.com/data', { key: 'value' })
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('错误:', error);
  });

总结

在React应用中,你通常不需要直接使用jQuery来处理Ajax请求,因为React本身提供了更现代化和更强大的方式来处理数据和异步操作。以下是使用React的一种典型方式:

使用Fetch API:

React可以与现代的Fetch API很好地结合使用。Fetch API是Web平台的新API,提供了一种更简单和强大的方式来处理HTTP请求。

import React, { useEffect, useState } from 'react';

const MyComponent = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        if (response.ok) {
          const result = await response.json();
          setData(result);
        } else {
          console.error('请求失败:', response.status, response.statusText);
        }
      } catch (error) {
        console.error('发生错误:', error);
      }
    };

    fetchData();
  }, []); // Empty dependency array means this effect runs once after initial render

  return (
    <div>
      {data ? (
        <div>
          {/* Render data as needed */}
          {data.map(item => (
            <div key={item.id}>{item.name}</div>
          ))}
        </div>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
};

export default MyComponent;

这个例子中,使用React的useEffect钩子来发起异步请求,并使用useState来更新组件状态。Fetch API的fetch函数用于发送HTTP请求,await关键字用于处理Promise。

使用Axios:

如果你更喜欢使用Axios,可以将Axios库添加到你的项目中,并使用它来简化HTTP请求:

npm install axios

然后在React组件中使用Axios:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const MyComponent = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get('https://api.example.com/data');
        setData(response.data);
      } catch (error) {
        console.error('发生错误:', error);
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      {data ? (
        <div>
          {/* Render data as needed */}
          {data.map(item => (
            <div key={item.id}>{item.name}</div>
          ))}
        </div>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
};

export default MyComponent;

使用Axios,你可以更简洁地处理HTTP请求,并利用其提供的一些方便的功能,比如请求拦截器和响应拦截器。

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...