Auto Import的功能是可以帮助我们自动删除无用的包Import(未被引用),以及自动Import填充尚未导入的包。
就算加上 [] 还是会被执行两次
import React, { useState, useEffect } from "react";
export default function StateFunction() {
const [num, setNum] = useState(1);
useEffect(() => {
console.log("@");
}, []);
return <div>这是一个函数组件 - {num}</div>;
}
三种方式解决:
1,在index.js取消react.strictMode
模式
2,在设置的参数的useEffect
中加非空判断
3,把初始化放到useReducer
里面
后面依赖项数组如果不写,就相当于添加了所有的依赖项,依赖项为[],则表示不依赖任何属性,这样useEffect就相当于只执行一次,ref.current是不变的,只有一个值,因为只执行了一次,否则相当于多次执行useEffect,每次重新执行setInterval 都会有一个新id
确实给力
你代码应该add了两次
https://gitee.com/sounmos/react-car这个地址可以下载
对于需要节流的渲染来说,可以使用useMemo或者useCallback来实现针对性的性能优化
useContext 只接收createContext创建出来的context。当前useLocalContext返回的是一个函数
不是vscode,是webstorm编辑器
useState('函数')
如果你想写成object, 要用{}包起来
更新函数可以接收一个修改值setNum(1),或是一个修改函数setNum(num => num + 1)。
const Child = () => { return <div>111</div> } const App = () => { const [num, setNum] = useState(1) const AppChild = useCallback(() => { return <Child /> }, [num]) return ( <div className="App" onClick={() => setNum(num + 1)}> <AppChild /> </div> ); }
类似于上述情况,如果当前num没有变化时,返回的依旧是之前计算好的Child内容,并不会重新计算Child组件。
https://gitee.com/sounmos/react-car
感谢认可?
useEffect 在渲染时是异步执行,并且要等到浏览器将所有变化渲染到屏幕后才会被执行。而useLayoutEffect 在渲染时是同步执行。
首先回答刚开始的时候的两次打印,这里是我们使用了getDoubleNum函数,所以打印,然后组件中通过setNum来更新了状态,在刷新页面的过程中又执行了一次,所以会出现两次输出。因为getDoubleNum这个函数是在jsx中引用的,每次渲染都会重新执行一次
可以在外层创建一个Context。当前页面在使用的时候无论是父组件还是子组件都使用同一个Context就可以
https://gitee.com/sounmos/react-car
https://gitee.com/sounmos/react-car
好吧,为了弥补,就在这里做回答吧,先看下代码实现
const [num, setNum] = useState(1) let timer // 第一个effect useEffect(() => { timer = setInterval(() => { console.log(1111); setNum(num + 1) }, 400) }, []) // 第二个effect useEffect(() => { console.log(num, timer); }, [num]) return ( <div className="App"> {num} </div> );
第一个effect在更新渲染的时候,并没有依赖num参数,也就是只执行一次就结束了,但是每次更新num的时候,当前组件是要刷新的,timer也会重新生成一个,此时的timer只是undefined,并没有赋值的过程(第一个effect不执行了)。第一次给timer赋值之后,剩下的所有更新里,timer都是undefined。所以在第二个effect里获取和清空timer,只能获取到undefined。
如果还有不明白,欢迎再次提问。?