理想是火,点燃熄灭的灯。
引入useState
import React, { useState } from 'react';
在无状态组件中去声明一个useState
function test() { // 解构赋值 useState传递的参数为初始值 跟前面的[num,setUnm] 没有关系。。 const [num,setNum] = useState(0) //在页面渲染这个值 return( <div> 你点击了 {num}次 <br/><br/> //每点击一次 即可增加 <button onClick={()=>{setNum(num+1)}}>点我</button> </div> ) }
使用这样的方式写组件很方便..
引入useEffect:
import React, { useEffect,useState } from 'react';
在组件中使用:
function tesst(){ const [num,setNum] = useState(0) // useEffect相当于是一个生命周期 异步 // 组件渲染完成后和组件更新时 调用 // componentDidMount 和 componentDidUpdate useEffect(()=>{ console.log(num) //return意思为解绑 当组件销毁时调用 return()=>{ console.log('老弟走了!') } // 空数组[]时,就是当组件将被销毁时才进行解绑 // 实现了componentWillUnmount的生命周期函数 },[]) }
// 1引用userContext和createContext来传参
import React, { useState,useContext,createContext } from 'react';
//2创建一个createContext上下文
const NumContent = createContext();
// 4.创建子路由
function Didi(){ // 4.1使用useContext来接收父组件传递的参数 let Num = useContext(NumContent) return( <h1>我是弟弟{Num}</h1> ) } function Exp2(){ const [Num,setNum] = useState(0) return( <div> <h1>{Num}</h1> <button onClick={()=>{setNum(Num+1)}}>点击增加</button> {/* 3.在组件中是引入NumContent.Provider 固定写法 value是要传递的参数 */} <NumContent.Provider value={Num}> {/* 5在组件NumContent.Provider内部写入 子组件 */} <Didi/> </NumContent.Provider> </div> ) } export default Exp2;
import React, { useReducer } from 'react'; // 创建一个reducer 传递两个参数 一个是传递的值 一个是如何控制这个值 function ReducerDemo(){ // useReducer需要传递两个参数 1一个是reducer本身,一个是初始值 // 前面的两个变量count是初始值,dispatch是派发器用来控制初始值 // useReducer本身中的state对应的是初始值,action对应的是dispatch传递的参数 const [count,dispatch] = useReducer((state,action)=>{ switch(action){ case 'add':{ return state+1 } case 'sub':{ return state-1 } default:{ return state } } },0) return( <div> <h2>现在的分数是{count}</h2> <button onClick={()=>dispatch('add')}>Increment</button> <button onClick={()=>dispatch('sub')}>Decrement</button> </div> ) } export default ReducerDemo
useMemo
主要用来解决使用React hooks产生的无用渲染的性能问题
问题描述:点击志玲按钮的时候 子组件的小白changeXiaobai()也会执行 又重复的渲染了一次
期望:点击相对应的按钮 只渲染相对应的组件 无相关的组件不重复的去渲染
解决方案:使用useMemo来规避重复渲染的问题
import React,{useState,useMemo} from 'react'; function Exp5(){ const [xiaobai,setXiaobai] = useState('小白正在等待') const [zhiling,setZhiling] = useState('志玲正在等待') return ( <div> <hr/> <button onClick={()=>{ setXiaobai(new Date().toLocaleTimeString()) }}> 小白 </button> <button onClick={()=>{ setZhiling(new Date().toLocaleTimeString()+'志玲来了') }}> 志玲 </button> <br/> <br/> {/* 向子组件传递两个值 */} {/* 如果传递在组件中 而不是以属性的方式传递,在子组件中使用children接收 */} <Child name={xiaobai} name2={zhiling}></Child> </div> ) } //子组件 function Child({name,name2,children}){ function changeXiaobai(name){ console.log('小白来了') return name +'你喊了一声小白 小白走过来了' } //使用useMemo 两个参数第一个是渲染的组件的方法 ,第二个是对应参数变化(条件) 下面的例子解释为只有name变化时候才 执行actionXiaobai() 这个函数 const actionXiaobai = useMemo(()=>changeXiaobai(name),[name]) return( <div> <div>{actionXiaobai}</div> <div>{name2}</div> </div> ) } export default Exp5
两个用处:用useRef
获取React JSX中的DOM元素、用useRef
来保存变量
import React,{useRef,useState,useEffect} from 'react'; // useRef获取React JSX中的DOM元素 // useRef来保存变量 function Exp6(){ // 声明一个dom变量 默认为Null 下面进行绑定 const inputEl = useRef(null) // 声明一个方法 const onButtonClick = ()=>{ inputEl.current.value = '你好彪哥' // console.log(inputEl.current.value ) } //保存变量 const textRef = useRef() const [text,setText] = useState('彪哥') useEffect(()=>{ textRef.current = text console.log('textRef.current',textRef.current) }) return ( <div> {/* 跟上面声明的inputEl进行绑定 */} <input ref={inputEl} type="text"></input> <button onClick={onButtonClick}>展示文字</button> <hr/> <input value={text} onChange={(e)=>{setText(e.target.value)}}></input> </div> ) } export default Exp6
一个自定义Hooks函数,要用use开头,区分出什么是组件,什么是自定义函数。 下面自定义Hooks函数获取窗口大小 import React,{useEffect,useState} from 'react'; function useSizeChange(){ //获取当前浏览器的宽高 let [size,setSize] = useState({ width:document.documentElement.clientWidth, height:document.documentElement.clientHeight }) //声明一个改变浏览器宽高的方法 let setSizeAction = () =>{ setSize({ width:document.documentElement.clientWidth, height:document.documentElement.clientHeight }) } //在useEffect周期函数中调用 useEffect(()=>{ window.addEventListener('resize',setSizeAction) //离开页面时解绑resize事件 return()=>{ window.removeEventListener('resize',setSizeAction) } },[]) // 把size返回出去 在下面Exp7函数中使用(相当于是一个闭包) return size } function Exp7(){ var size = useSizeChange() return ( <div> 窗口的Sizi:{size.width}*{size.height} </div> ) } export default Exp7
作者: Bill 本文地址: http://biaoblog.cn/info?id=1574931180000
版权声明: 本文为原创文章,版权归 biaoblog 个人博客 所有,欢迎分享本文,转载请保留出处,谢谢!