React学习一:环境搭建、JSX基础、事件绑定、组件使用、样式控制
一、概念
React由Meta公司研发,是一个用于构建Web和原生交互界面的库。
react中文文档地址:https://zh-hans.react.dev/learn
React的优势
相较传统基于DOM开发的优势:组件化的开发方式;不错的性能
相较于其他前端框架的优势:丰富的生态;跨平台支持
二、环境搭建
首先和vue项目一样,项目创建工具和包管理工具都是基于nodejs,需要配置好nodejs。react项目创建工具是create-react-app,创建项目的命令如下(默认创建的项目是一个js项目,如果需要创建一个ts的项目使用第二个命令)
npx create-react-app 项目名
npx create-react-app 项目名 --template typescript
创建过程比较慢,多等会。创建好后看一下项目结构,可以看出和vue项目的层级结构很像,有存放依赖的目录node_models,有public和src等。重点看src目录下面的App.js和index.js两个文件,index.js是整个项目的入口,里面导入了React、ReactDOM这两个核心包,还导入了App.js根组件。然后找到public目录下面index.html中的root节点,最后将根组件挂载到root节点上。
概念: JSX是JavaScript和XML (HTML) 的缩写,表示在JS代码中编写HTML模版结构,它是React中编写UI模版的方式
本质:JSX并不是标准的JS语法,它是JS的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行
优势:1. HTML的声明式模版写法(响应式数据)2. JS的可编程能力
识别js表达式(注意:一定是表达式,是一个有值的式子),react就是使用大括号来拿值并显示,值可以是表达式,可以是简单的常量,也可以是对象数组等。如果是数组和对象,用起来感觉和...展开运算符很想,去掉最外面的一层括号。
1.使用引号传递字符串
2.使用JavaScript变量
3.函数调用和方法调用
4.使用JavaScript对象
const count = 100 function getName(){ return 'along' } function App() { return ( <div className="App"> {'this is App'}<br/> {count}<br/> {getName()}<br/> <div style={{color:'red'}}>this is div</div><br/> </div> ) }
列表渲染:使用map遍历渲染,每个li标签需要加上一个唯一的key(字符串或number),key在react框架内部使用,提升更新性能。
const list = [ {id:1000,name:"long0"}, {id:1001,name:"long1"}, {id:1002,name:"long2"}, ] function App() { return ( <div className="App"> <ul> {list.map(item=><li key={item.id}>{item.name}</li>)} </ul> </div> ) }
简单条件渲染
const isLogin = true function App() { return ( <div className="App"> {isLogin && <span>this is span</span>}<br/> {isLogin ? <span>longyi</span> : <span>longer</span>}<br/> </div> ) }
复杂条件渲染
const articleType = 1 function getArticleTim(){ if(articleType === 1){ return <div>我是单图模式</div> }else if(articleType === 2){ return <div>我是双图模式</div> }else{ return <div>我是多图模式</div> } } function App() { return ( <div className="App"> {getArticleTim()} </div> ) }
四、事件绑定
语法: on+事件名称= {事件处理程序},整体上遵循驼峰命名法
如果不传参数或只传事件对象,那么事件处理程序里面直接写函数名就可以了,只传事件对象要在函数里面加形参e。
传递自定义参数
语法:事件绑定的位置改造成箭头函数的写法,在执行clickHandler实际处理业务函数的时候传递实参。注意:不能直接写函数调用,这里事件绑定需要一个函数引用
function App() { const handleClick = (name,e) => { console.log(name,e) } return ( <div className="App"> <div> <button onClick={(e)=>handleClick('along',e)}>click me</button> </div> </div> ) }
五、组件
概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次
在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图U,渲染组件只需要把组件当成标签书写即可
const Button = () => { return <div>click me</div> } function App() { return ( <div className="App"> <Button/> </div> )
六、useState
数据驱动视图,也就是vue里面的响应式数据。和vue实现的方式还是有区别的,vue中只需要用ref或reactive声明一个变量就可以实现响应式了,值改变,页面中的值也变。react中则不同,变量的值不能直接修改,直接修改视图中的值不变,必须使用set函数来修改才行。
1. useState是一个函数,返回值是一个数组
2.数组中的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
状态不可变
在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新
修改对象状态
规则:对于对象类型的状态变量,应该始终传给set方法-一个全新的对象来进行修改
import {useState} from 'react' function App() { const [num,setNum] = useState(0) const handleButton = () => { setNum(num+1) } const [form,setForm] = useState({name:'along'}) const handleForm = () => { setForm({...form,name:'jack'}) } return ( <div className="App"> <button onClick={handleButton}>{num}</button><br/> <button onClick={handleForm}>{form.name}</button><br/> </div> ) }
注:useState函数生成的set函数是异步的,如果使用set函数后面直接使用变量可能仍旧是旧值没有更新。
七、基础样式控制
1、行内样式(不推荐)
2、class类名控制
import './index.css' function App() { return ( <div className="App"> <span className='foo'>this is class fool</span> </div> ) }
练习的几个常见功能
列表渲染:数组中使用map方法遍历生成,其中列表可以封装成一个组件
import { useState } from 'react' function App() { const [commentList, setCommentList] = useState([ { rpid: uuidv4(), content: '第一条评论', time: dayjs(new Date()).format('MM-DD hh:mm') } ]) return ( <div> {commentList.map(item => <div key={item.rpid}> <span>{item.rpid}</span> <span>{item.content}</span> <span>{item.time}</span> </div>)} </div> ) } export default App
删除功能:使用数组中filter函数过滤要删除的元素
导航栏切换实现高亮提示:1.点击谁就把谁的type记录下来 2.通过记录的type和每项遍历时的type做匹配 控制激活类名的显示
import { useState } from 'react' import './index.css' const tabs = [ {type:'hot',name:'最热'}, {type:'new',name:'最新'} ] function App() { const [type,setType] = useState('hot') return ( <div> {tabs.map(item=><span className={`${type===item.type ? 'active' : false}`} key={item.type} onClick={()=>setType(item.type)}>{item.name}</span>)} </div> ) } export default App
排序,使用插件lodash,地址:https://lodash.com/docs/4.17.15#orderBy