useState想要保存函数的坑
useState右边括号中初始值为类似0这种类型的时候,其左边数组中初始值的类型也就为对应的number类型;
用一句简单的话来说,右边赋什么,左边就是什么,也就是说useState是能存储这些数据的,但是有一种类型除外,就是函数,见下图
当右边为函数的时候,左边居然为void类型,怎么解决??
只需将你想要保存的函数作为返回值即可!(其实这里利用了惰性加载,参见例a旁的注解)
const [fn,setFn ] = React.useState(()=>()=>{});
useState中保存函数的实战与方案
注意比较下面的两个例子:
例a:(注意:useState中的函数一开始渲染的时候会立即执行!就是说useState右边括号中的函数在组件的初始渲染中会立即执行)
例b:(完成了对函数的保存与更改)
import React from"react"; import"./styles.css"; exportdefaultfunction App2() { const [fn, setFn] = React.useState(() =>() => { alert("I am init function"); }); console.log("fn: ", fn); return ( <div className="App"> <button onClick={() => setFn(() => () => alert("update function"))}> setCallback </button> <button onClick={fn}> callback </button> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ); }
使用useRef的解决方案
使用useRef解决这个问题的坑:
import React from"react"; import"./styles.css"; exportdefaultfunction App3() { const callbackRef = React.useRef(() => { alert("I am init function"); }); const callback = callbackRef.current console.log("callback: ", callback); return ( <div className="App"> <button onClick={() => (callbackRef.current=() => alert("update function"))}> setCallback </button> <button onClick={callback}> callback </button> {/*s12*/} <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ); }
点击callback按钮:
点击setCallback:
再次点击callback按钮(发现没有变化,调用的还是原来的函数)
上面问题的原因是什么?
useRef不是state,用useRef定义的只是普通的变量,不是本组件的状态,useRef这个容器里保存的值改变的时候,state不会改变,故不会触发渲染;
故s12处的callback还是第一次渲染时的callback!怎么解决这个问题??
只要将改变之后的callbackRef.current()
重新读取出来即可,而不是读取之前的那个值
import React from"react"; import"./styles.css"; exportdefaultfunction App4() { const callbackRef = React.useRef(() => alert("I am init function")); const callback = callbackRef.current; console.log("callback: ", callback); return ( <div className="App"> <button onClick={() => (callbackRef.current = () => alert("update function"))} > setCallback </button> {/*下面一行很重要!!!如果写成callbackRef.current也还是不行,这样读取的还是之前的值,并没有重新读取 */} <button onClick={() => callbackRef.current()}> call callback </button> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ); }
总结
本文主要小结了useState是如何保存函数的,主要是采用柯里化的方式,即类似于如下这种解决方式(主要是将你想要保存的函数作为返回值):
const [fn, setFn] = React.useState(() =>() => { console.log("I am Currying") });
至此,又解决了一个useState的坑