最近我的项目用了 umi3+react17+antd pro5

我的项目中遇到的useState的坑

1.useState不适宜简单对象的更改

因为useState不能像setState那样进行合并更新,当应用useState第二个参数进行数据更新的时候,必须传入一个残缺的构造,而不仅仅只是扭转的那一部分。

2.useState异步回调的问题

当应用usestate对数据进行更新,并不能立即获取到最新的数据。

const [name, setName] = useState('dx');const handleTest = () => {  console.log(name) // dx  setName('dx1')  console.log(name) // dx}

解决方案

一、配合useEffect应用

const [name, setName] = useState('dx');const handleTest = () => {  console.log(name) //dx  setName('dx1')  console.log(name)//dx}  useEffect(() => {  console.log(name) //dx1},[name])

二、创立一个新的变量保留最新的数据

const [name, setName] = useState('dx');const handleTest = () => {  console.log(name) //dx  const newName = "dx1"  setName(newName)  console.log(newName) //dx1}

3.依据hook的规定,应用useState的地位有限度

  • 仅顶层调用 Hook :不能在循环,条件,嵌套函数等中调用useState()。
  • 在多个useState()调用中,渲染之间的调用程序必须雷同。
  • 仅从React 函数调用 Hook:必须仅在函数组件或自定义钩子外部调用useState()。

4.应用useState,回调函数模式更改数据

const [a, setA] = useState({c:1})/** oldA为之前的a,return为设置的新值 */setA((oldA) => {  return {c: oldA.c + 1}})

5.useState存入的值只是该值的援用(援用类型)

const textObj = {name:'dx'}const [useState1, setUseState1] = useState(textObj )const [useState2, setUseState2] = useState(textObj )/** usestate的操作不要放在函数的最外层,这里只是简略的代码展现,你能够将set操作放在某个函数外面 */setUseState1((oldUseState1) => {  oldUseState1.age = 18  return {...oldUseState1}})useEffect(() => {  /** 扭转一个会导致两个都扭转,深浅拷贝的问题 */  console.log(useState1)  // {name: "dx", age: 18}  console.log(useState2)  // {name: "dx", age: 18}},[useState1])

解决的计划

const textObj = {name:'dx'}const [useState1, setUseState1] = useState(textObj )const [useState2, setUseState2] = useState(JSON.parse(JSON.stringify(textObj)))/** usestate的操作不要放在函数的最外层,这里只是简略的代码展现,你能够将set操作放在某个函数外面 */setUseState1((oldUseState1) => {  oldUseState1.age = 18  return {...oldUseState1}})useEffect(() => {  /** 扭转一个会导致两个都扭转,深浅拷贝的问题 */  console.log(useState1)  // {name: "dx", age: 18}  console.log(useState2)  // {name: "dx"}},[useState1])

6.useState,如果保留援用数据,useEffect检测不到变动?

const textObj = {name:'dx'}const [useState1, setUseState1] = useState(textObj)/** usestate的操作不要放在函数的最外层,这里只是简略的代码展现,你能够将set操作放在某个函数外面 */setUseState1((oldUseState1) => {  oldUseState1.age = 18  return oldUseState1}useEffect(() => {  console.log(useState1)  },[useState1])//后果是没有任何反馈

解决办法

const textObj = {name:'dx'}const [useState1, setUseState1] = useState(textObj)/** usestate的操作不要放在函数的最外层,这里只是简略的代码展现,你能够将set操作放在某个函数外面 */setUseState1((oldUseState1) => {  oldUseState1.age = 18  /** 返回一个新的对象,useEffectc能力检测失去 */  return {...oldUseState1}}useEffect(() => {  console.log(useState1)  // {name: "dx", age: 18}},[useState1])

7.useState无奈保留一个函数

你是否尝试着将函数的援用作为一个变量保留到useState中去呢?
比方:

const testFunciton1 = () => {  console.log({name: 'dx',age: '18'})}/** usestate保留函数测试 */const [stateFunction, setstateFunction] = useState<() => void>(testFunciton1);useEffect(() => { console.log(stateFunction)// {name: 'dx', age: 18}}, [stateFunction])

代码中从未调用过testFunciton1 ,后果testFunciton1却被执行了
useEffect打印进去的却是一个undefined。

略微改变一下代码,再测试

const testFunciton1 = () => {  console.log({name: 'dx',age: '18'})  return {    name: 'yx',    age: '17'  }}/** usestate保留函数测试 */const [stateFunction, setstateFunction] = useState<() => void>(testFunciton1);useEffect(() => { console.log(stateFunction)// {name: 'dx', age: 18} // {name: 'yx', age: 17}}, [stateFunction])

很显著,在useState中,函数会主动调用,并且保留函数返回的值,而不能保留函数自身。

解决的计划
应用useState不能保留函数,那么能够应用useCallback这个hook。

/** useCallback,应用参数与useEffect统一 */const testFunction = useCallback(() => {  // useCallback返回的函数在useCallbak中构建  const testFunciton1 = () => {    console.log({ name: 'dx', age: '18' });    return {      name: 'yx',      age: '17',    };  };  return testFunciton1;}, []);useEffect(() => {  console.log(testFunction());// 打印的是函数}, [testFunction]);