当前位置: 首页 > Web前端 > HTML5

React源码阅读-8_039

时间:2023-04-05 23:21:46 HTML5

React源码阅读-8ReactHooksHook是React16.8的新特性。它让您无需编写类即可使用状态和其他React功能。import{useCallback,useContext,useEffect,useImperativeHandle,useDebugValue,useLayoutEffect,useMemo,useReducer,useRef,useState,useResponder,}from'./ReactHooks';useState返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理程序或其他一些地方调用这个函数。类似于类组件的this.setState,但不会合并新旧状态;importReact,{useState}from"react";import"./App.css";functionApp(){const[count,setCount]=useState(0);return(

您点击了{count}次

setCount(count+1)}>点击我
);}exportdefaultApp;useEffectimportReact,{useState,useEffect}来自"react";import"./App.css";functionApp(){const[count,setCount]=useState(0);useEffect(()=>{//使用浏览器API更新文档标题document.title=`您点击了${count}次`;});返回(

你点击了{count}次

setCount(count+1)}>点我
);}exportdefaultApp;相当于React类的生命周期函数,可以把useEffectHook看成三个函数的组合:componentDidMount、componentDidUpdate和componentWillUnmount。默认情况下,效果会在每一轮组件渲染中完成。在这种情况下,一旦效果的依赖项发生变化,就会重新创建。可以将第二个参数传给useEffect,它是一个效果所依赖的值数组。更新后的示例如下所示:useEffect(()=>{constsubscription=props.source.subscribe();return()=>{subscription.unsubscribe();};},[props.source],);如果你想执行一个只运行一次的效果(仅当组件被挂载和卸载时),可以传递一个空数组([])作为第二个参数。这告诉React你的效果不依赖于props或state中的任何值,所以它永远不需要重新执行。这不是特例-它仍然遵循输入数组的工作方式。useContext类似于前面提到的上下文Contextconstvalue=useContext(MyContext);接收一个上下文对象(React.createContext的返回值)并返回上下文的当前值。当前上下文值由上层组件中离当前组件最近的的valueprop决定。constthemes={light:{foreground:"#000000",background:"#eeeeee"},dark:{foreground:"#ffffff",background:"#222222"}};constThemeContext=React.createContext(themes.light);functionApp(){return();}functionToolbar(props){返回(
);}functionThemedButton(){常量主题=useContext(ThemeContext);return(我是按主题上下文设置样式的!);}useContext的参数必须是上下文对象本身useReducerconst[state,dispatch]=useReducer(reducer,initialArg,init);接收一个形式为(state,action)=>newState的reducer,返回当前状态及其匹配的dispatch方法。它类似于redux。实现的计数器constinitialState={count:0};functionreducer(state,action){switch(action.type){case"increment":return{count:state.count+1};case"decrement":return{count:state.count-1};默认值:抛出新的错误();}}functionApp(){const[state,dispatch]=useReducer(reducer,initialState);return(<>Count:{state.count}dispatch({type:"decrement"})}>-dispatch({type:"increment"})}>+);}指定初始状态const[state,dispatch]=useReducer(reducer,{count:initialCount});延迟初始化你可以选择延迟创建初始状态为此,你需要将init函数作为useReducer的第三个参数传递,这样初始状态将被设置为init(initialArg)。functioninit(initialCount){return{count:initialCount};}functionreducer(state,action){switch(action.type){case'increment':return{count:state.count+1};case'decrement':return{count:state.count-1};case'reset':returninit(action.payload);默认值:抛出新的错误();}}functionApp({initialCount}){const[state,dispatch]=useReducer(reducer,initialCount,init);return(<>Count:{state.count}dispatch({type:'reset',payload:initialCount})}>重置dispatch({type:'decrement'})}>-dispatch({type:'increment'})}>+/>);}跳过dispatch如果ReducerHook的返回值与当前状态相同,React会跳过子组件的渲染和副作用的执行作为参数传递给useCallback,它返回回调函数的记忆版本当您将回调传递给经过优化的子组件并使用引用相等性来避免不必要的渲染(例如shouldComponentUpdate)时,仅在依赖项更改时更新才有用。constmemoizedCallback=useCallback(()=>{doSomething(a,b);},[a,b],);useRefuseRef返回一个可变的ref对象,其.current属性被初始化为传递的参数(initialValue)。返回的ref对象在组件的整个生命周期中持续存在。和前面的ref、forwardref、createref类似,只不过这个是functionTextInputWithFocusButton(){constinputEl=useRef(null);constonButtonClick=()=>{//`current`指向DOM上挂载的A文本输入元素inputEl.current.focus();};return(<>聚焦输入);}useMemoconstmemoizedValue=useMemo(()=>computeExpensiveValue(a,b),[a,b]);将“创建”函数和依赖项数组作为参数传递给useMemo,它只会在项目发生变化时才重新计算memoized值。这种优化有助于避免在每次渲染时进行昂贵的计算。类似memo等API,就不展开描述了,感觉差不多https://zh-hans.reactjs.org/d...

猜你喜欢