React基础
目录
- 一、开发环境搭建
- 二、状态
- 1.状态驱动
- 2.列表渲染
- 三、参数
- 1.组件开发
- 2.父组件向子组件传参
- 3.子组件向父组件传参
- 四、副作用Hooks
- 1.useState()
- 2.useEffect()
- 3.useRef()
- 4.useActionState()
一、开发环境搭建
当前主流方案是使用Vite脚手架:
npmcreate vite@latest 项目名--template=react-ts二、状态
1.状态驱动
传统开发依靠JavaScript+Ajax定位DOM元素并绑定事件,依靠事件驱动页面变化。
React、Vue属于状态驱动,根据状态的变化实时更新页面,封装了事件驱动的过程,只关注页面结果。
// 其中,在JavaScript中编写的HTML在编译阶段会被编译成JavaScript:<h1 className="title">Hello World</h1>// 实际上会被编译成:React.createElement('h1',{className:'title'},'Hello World');状态驱动即根据参数的值返回不同的HTML代码块,如果要基于某个参数的状态实时更新页面必须要使用useState(0)定义参数:函数传入初始值和格式,返回状态变量和状态更新函数。
状态更新函数不仅会更新变量,还会触发该组件的一次重新渲染。由于状态变量具有不可变性,因此状态更新函数更新变量的原理是将新的状态变量赋值给引用。
exportfunctionApp(){// 状态const[count,setCount]=useState(0)// 视图return<div onClick={()=>setCount(count+1)}>{count}</div>}而以下方式参数变化不会引起页面变化:
exportfunctionApp(){// 状态letcount=0// 视图return<div onClick={()=>count+1}>{count}</div>}2.列表渲染
import{useState}from'react'interfaceUser{id:stringname:string}exportconstListDemo=()=>{const[userId,setUserId]=useState('')const[userName,setUserName]=useState('')const[userList,setUserList]=useState<User[]>([])constaddUser=()=>{if(!userId||!userName)return// ...userList将旧数组数据取出。并追加一条新用户数据,用新数组更新状态变量setUserList([...userList,{id:userId,name:userName}])setUserId('')setUserName('')}return(<div><input value={userId}onChange={(event)=>setUserId(event.target.value)}/><input value={userName}onChange={(event)=>setUserName(event.target.value)}/><button onClick={addUser}>+</button><ul>{userList.map((item)=>(<li}>{item.id}-{item.name}</li>))}</ul></div>)}三、参数
1.组件开发
组件开发即解耦页面为多个不同功能的组件,便于复用。
组件定义规范如下:
- 组件参数一般用接口定义,参数可以是变量、函数。
- 使用export将子组件暴露出去,其他文件可以通过import导入。
- 组件返回值是HTML代码块,可以根据参数渲染不同内容。
import{useState}from"react"interfaceHelloWorldProps{title:string,render?:()=>React.ReactNode}exportconstHelloWorld=(props:HelloWorldProps)=>{const{title,render}=props;const[count,setCount]=useState(0);return<div>{title}<br/>{count}<button onClick={()=>{setCount(count+1)}}>+</button>{render?.()}</div>}2.父组件向子组件传参
父组件通过组件属性向子组件传递参数,子组件使用函数形参捕获。
import'./App.css'import{HelloWorld}from'./components/HelloWorld/index'exportfunctionApp(){return<HelloWorld title='这是父组件向子组件传递参数'render={()=>{return<div>这是父组件向子组件传递的函数</div>}}/>}import{useState}from"react"interfaceHelloWorldProps{title:string,render?:()=>React.ReactNode}exportconstHelloWorld=(props:HelloWorldProps)=>{const{title,render}=props;return<div>{title}<br/>{render?.()}</div>}3.子组件向父组件传参
父组件通过组件属性向子组件传递由父组件编写的回调函数,子组件调用父组件的回调函数并传入参数,父组件就能通过函数体拿到子组件传入的参数。
exportfunctionApp(){const[num,setNum]=useState(0);return<div><HelloWorld handle={(msg:number)=>{setNum(msg)}}/><div>子组件向父组件传来的值:{num}</div></div>}import{useState}from"react"interfaceHelloWorldProps{handle?:(count:number)=>void}exportconstHelloWorld=(props:HelloWorldProps)=>{const{handle}=propsconst[count,setCount]=useState(0);return<div>{count}<button onClick={()=>{setCount(count+1);handle?.(count+1)}}>+</button></div>}四、副作用Hooks
Hook赋予组件能使用 state 状态、生命周期的能力,将静态组件动态化。
1.useState()
useState(0)用于维护状态变量,通过状态更新函数更新变量会触发该组件的一次重新渲染:
exportfunctionApp(){// 状态const[count,setCount]=useState(0)// 视图return<div onClick={()=>setCount(count+1)}>{count}</div>}2.useEffect()
useEffect()用于监听状态变量的变化,当状态变量发生变化时执行函数体:
import'./App.css'import{useEffect,useState}from'react'exportfunctionApp(){// 状态const[count,setCount]=useState(0)//副作用useEffect(()=>{console.log({count})},[count])// 视图return<div onClick={()=>setCount(count+1)}>{count}</div>}useEffect(()=>{},[prop]),状态变量发生变化时执行useEffect(()=>{}),组件发生变化后执行useEffect(()=>{},[]),仅组件挂载阶段执行
3.useRef()
useRef()用于获取DOM和缓存变量。
import'./App.css'import{useRef}from'react'exportfunctionApp(){// div对象constdivRef=useRef<HTMLDivElement>(null)return<div ref={divRef}></div>}4.useActionState()
useActionState()用来获取表单提交状态和返回值。
import{useActionState}from"react"exportconstFormDemo=()=>{consthandleSubmit=async(formData:FormData)=>{constname=formData.get("name")console.log({name})awaitapi.post("/user",{name})return{}}const[state,actions,pending]=useActionState(handleSubmit,null)console.log("当前提交状态和返回值",state)return(<form action={actions}><input type="text"name="name"/><button type="submit">提交</button></form>)}