总结

 

React--Query使用(v5)

当依赖项为undefined、null、'' 时(视为无效参数),不发起请求

查看代码

function Todos() {
  const [filter, setFilter] = React.useState('')
​
  const { data } = useQuery({
      queryKey: ['todos', filter],
      queryFn: () => fetchTodos(filter),
      // ⬇️ disabled as long as the filter is empty : 只要筛选器为空,就会被禁用
       // 只有 filter 变化、且不为空时,发起请求
      // 避免值为空时发起的无意义请求(值为空请求就会失败,react-query会不断进行请求,造成浪费)
      enabled: !!filter
  })
  ...
  ..
  .
}

 

React 有状态函数组件 依然是纯函数

见Meta(FaceBook工程师 黄玄 回答)
​
https://www.zhihu.com/question/537538929

??

​
value1 ?? value2
​
?? 在value1和value2之间,只有当value1为null或者 undefined 时取value2,否则取value1(0,false,""被认为是有意义的,所以还
​
是取value1)

typescript 类型断言

as

let student = {}
// let student: {}
​
student.name = 'jack'
// 类型“{}”上不存在属性“name”。
​
student.age = 18
// 类型“{}”上不存在属性“age”。
​
// 接口
interface Person{
  name:string;
  age: number
}
​
let student = {} as Person
// let student: Person
​
student.name = 'jack' // 不会再报错
student.age = 18

<>

function getLength(something: string | number): number {
    return (<string>something).length;
}
​
let a: any
let b = <string>a // string
注意: <>断言在react组件中与jsx语法冲突!,一般不可用。

!(非空断言)

let num:number | null | undefined
// let num: number | null | undefined 
​
// let num2 = num.toFixed(2)
// num可能为 “null” 或“未定义”
​
let num2 = num!.toFixed(2) // string

双重断言

<span>{console.log("render") as unknown as string}</span>

超时报错、未超时正常返回数据

模拟请求数据的方法

/**
 * 假设该数据请求函数 n s 后才能返回数据
 * @returns Promise<any>
 */
function queryfn() {
  return new Promise(function (reslove) {
    setTimeout(function () {
      console.log("1111");
      reslove(true);
    }, 5000);
  });
}

type one

/**
 *
 * @param {Promise<any>} queryfn 请求数据的函数
 * @param {number} delaty 超时的时限,超时报错
 */
function isTimeOut(queryfn, delaty = 4000) {
  new Promise(function (reslove, reject) {
    setTimeout(function () {
      reject(new Error("request timeout!"));
    }, delaty);
​
    console.log("111");
    queryfn().then((res) => {
      console.log("res----->", res);
      reslove(res);
    });
  });
}
​
// console.log("isTimeOut", isTimeOut(queryfn, 6000));

type two

/**
 * 
 * @param {Promise<any>} p1 
 * @param {number} timeout 
 * @returns 
 */
const timeoutReject = (p1, timeout = 3000) => {
  const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("网络超时");
    }, timeout);
  });
  return Promise.race([p1, p2]);
};
​
timeoutReject(queryfn())
  .then((res) => {
    console.log("result", res);
  })
  .catch((err) => {
    console.log("error", err);
  });

若请求前的先决条件不满足,多次调用直到满足

​
// 先决条件
​
function isOK() {
  return false;
}
​
function getData() {
  return "data";
}
​
/**
 * 
 * @param {() => boolean} queryfn 会返回 true 或 false
 * @param {() => Promise<any>} callback 请求数据的方法
 * time: 重新调用的时间间隔、以1.5倍递增,若去除则每次调用时间一样
 */
​
function simplePoller(queryfn, callback) {
  let time = 1000;
​
  const poll = () => {
    console.log("time", time);
    if (queryfn()) {
      callback();
      return;
    }
    setTimeout(poll, time);
    time *= 1.5
  };
  setTimeout(poll, time);
}
​
console.log("deepQuery", simplePoller(isOK, getData));

请求出错,重试次数

  function likeData() {
    return new Promise(function (reslove, reject) {
      // reject("请求出错");
      setTimeout(() => {
        reslove("jieguo");
      }, 5000);
    });
  }

type one

  // 请求失败重试指定的次数
  function retryFunc(likeData, trymax) {
    let num = 0;
​
    function autopoll(reslove) {
      num++;
      if (num > trymax) {
        return;
      }
      likeData()
        .then((res) => {
          console.log("res", res);
          reslove(res);
        })
        .catch((err) => {
          console.log("eerrr", err);
          setTimeout(autopoll, 5000);
        });
    }
​
    return new Promise(function (reslove, reject) {
      // setTimeout(function () { //  混合超时报错(可选)
      //   reject("timeout");
      // }, 5000);
      autopoll(reslove);
    });
  }
​
  // console.log("retryFunc", retryFunc(likeData, 6));

type two

  // 另一个版本
​
  function retryTwo(likeData, max) {
    let num = 0;
​
    function poll() {
      return likeData()
        .then((res) => {
          // if (res.code !== 200) {
          //   throw new Error("requst failed!");
          // }
          // return res.data;
          return res;
        })
        .catch((err) => {
          num++;
          console.log("eeeeeeee", err);
          if (num < max) {
            setTimeout(function () {
              poll();
            }, 2000);
          } else {
            throw new Error(`已经连续请求${num}次`);
          }
        });
    }
​
    return poll();
  }

jsx不能console?

<span>{console.log("render")}</span>
​
不能将类型“void”分配给类型“ReactNode”。ts(2322)
index.d.ts(1376, 9): 所需类型来自属性 "children",在此处的 "DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>" 类型上声明该属性
​

解决

<span>{console.log("render") as unknown as string}</span>
 
posted @ 2023-04-10 14:41  KarlFranz  阅读(73)  评论(0)    收藏  举报