reacd基础语法
// 01有且只有一个根节点 // 02{}写js // 03{/**}注释
1.JXS语法
//从react 的包当中引入了 React。只要你要写 React.js 组件就必须引入React,因为react里有一种语法叫jsx,要写SX,就必须引入React import React from 'react'; //导入组件 import App from './all/index1' import { createRoot } from 'react-dom/client'; const rootElement = document.getElementById('root'); const root = createRoot(rootElement); // 创建一个根 root.render(<App />); // 将组件渲染到页面上 // RealtDow可以帮助我们把 React组件渲染到页面上去,没有其它的作用了。它是从、react-dom 中引入的,而不是从 react引入。 //JSx一使用react构造组件,bable进行编译—> JavaScript对象一ReactDOM.render( ->DOM元素一>插入页面
1.1文本渲染,条件渲染,数组列表的渲染,富文本渲染
function App(params) { const text1 = '文本渲染' const text2 = '<strong style="color:red;">文本渲染</strong>' const isstage = true const age = 20 const arr1 = [<span key="1">1</span>, <span key="2">2</span>, <span key="3">3</span>, <span key="4">4</span>] const arr2 = ['js', 'vue2', 'vue3', 'react'] return ( <div> <h3 className='h'>文本渲染</h3> <p>{text1}</p> {/*富文本:dangerouslySetInnerHTML={{ __html: text2 }}*/} <p dangerouslySetInnerHTML={{ __html: text2 }}></p> <h3 className='h'>条件渲染</h3> {/*{条件?<p>true展示</p>:<p>false展示</p>}*/} {isstage ? <p>主线模式</p> : <p>游客模式</p>} {/*{条件?<p>true展示</p>:<p>false展示</p>}*/} {age > 18 && <p>网吧反应呢</p>} <h3 className='h'>数组列表的渲染</h3> {/* 数组会自动展开*/} {arr1} {/*map从现有的数组,映射出新的数组*/} {/*{arr.map((item,index)=><p key={index}>{item}</p>)}*/} {arr2.map((item, index) => <p key={index}>{item}</p>)} </div> ) } export default App
2.组件
class类组件
//又叫容器组件,有this,ref,生命周期,state,也有props,不可以使用hooks //imrc 导入React 和React.Component 类型 import React, { Component } from 'react' //创建并导出类组件 export default class App extends Component { render() { return (<div>莫峰阁</div>) } }
函数组件
//又叫功能组件,视图组件,只有props,没有this,ref,生命周期,state,可以使用hooks //提倡多使用函数组件,多使用props,没有this,和生命周期,更加解耦,复用性更强 function App(){ return ( <div>hello functional component<div>1111</div> ) } export default App
组件的嵌套
function Swiper(){ return <div>swiper</div> } const Tabbar =()=>{return <div>tabbar</div>} export default cLass App extends Component { render() { return ( <div> <Swiper></Swiper> <Tabbar></Tabbar> </div> ) } }
3.组件的样式
// class要用className表达 // 样式推荐使用对象方式驼峰写法 import React, { Component } from 'react' import './index1.css' //2:也可以从外部引入 export default class App extends Component { render() { var style = { backgroundColor: 'yellow' } return ( <dic> <div> <span>{10 + 20}-{myname}</span> {/*{}为jsx的语法模板*/} <10>20? 'aaa':' bbb'> {/*三元运算符*/} </div> <div> {/* React推荐我们使用行内样式,因为React觉得每一个组件都是一个独立的整体*/} {/*1:行内样式*/} <span style={{ backgroundColor: 'red' }}>1111</span> <span style={style}>1111</span> <span className='one'>1111</span> </div> ) } }
4.事件绑定
React并不会真正的绑定事件到每一个具体《》的元素上,而是采用事件代理的模式
import React, { Component } from 'react' export default class App extends Component { show(str='111'){ console.log(this); alert(str) } render() { return ( <button onClick={()=>{console.log(this);}}> add1</button> {/*这里打印的为组件App实例*/} <button onClick={this.add}> add2</button> {/*345*/} <button onClick={()=>{this.add()}}> add3</button> {/*这里直接无须点击直接打印345,并且再次点击也无效果*/} <h3>事件传参</h3> <button onClick={this.show.bind(this,'666')}>点击</button> <button onClick={()=>{this.show('777')}}>点击</button> <h3>事件相应</h3> <button onClick={this.show}>点击</button> <button onClick={()=>{this.show()}}>点击</button> ) } add(){console.log(345)} }
5.Ref的应用
1给标签设置ref="mytext" 通过这个获取this.refs.mytext , ref可以获取到应用的真实domr
myref = React.createRef() render() { return ( <div> <input ref="mytext" /> <button οnclick={ ()=>{console.log("click1" , this.refs.mytext.value)} }> add1 </button> {/*这里this.refs.mytext获取的是真实的dom*/} </div> ) }
2给组件设置ref="username" 通过这个获取this.refs.username ,ref可以获取到组件对象
6.组件的数据挂载方式
1、状态(state)
状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理)
(1)定义state
第一种方式
import React,{ Component } from 'react' export default cLass App extends Component { stata = { text:'收藏'} render() { return ( <div> <h1>欢迎来到react开发</h1> <button οnclick={()=>{this.setstate({text:'取消收藏'})}> {this.state.text} </button> </div> ) } } {/*this.state是纯js对象,在vue中,data属性是利用object.defineProperty 处理过的,更改data的数据的时候会触发数据的getter和setter,但是React中没有做这样的处理,如果直接更改的话,react是无法得知的,所以,需要使用特殊的更改状态的方法setstate。 */}
第二中方法
import React,{ Component } from 'react' export default cLass App extends Component { constructor(){ super()//继承组件类的所有属性 this.state = {text:"收藏"} } render() { return ( <div> <h1>欢迎来到react开发</h1> <button οnclick={()=>{this.setstate({text:'取消收藏'})}> {this.state.text} </button> </div> ) } }
7.循环渲染
export default class App extends Component { state = {list:[ "1111", "2222","3333"]} render(){ return ( <div> <ul>{this.state.list.map(item=><li key={item}>{item}</li>)}</ul> </div> ) } }
9.表单双向绑定
//imrc导入React 和React.Component 类型 import React, { Component } from 'react' //cc 创建一个App的类继承Component class App extends Component { state = { num:5 } updataNum = (val=1)=>{ this.setState({num:this.state.num+val}) } render() { return ( <div> <h3>状态state</h3> <p>{this.state.num}</p> <button onClick={()=>this.updataNum(2)}>+2</button> <button onClick={()=>this.updataNum(-2)}>-2</button> <h3>表单双向绑定</h3> <input value={this.state.num} onChange={e=>this.setState({num:e.target.value*1})}/> </div> ); } } export default App;
10,组件
1,父组件
import Counter from './component/Counter' import React, { Component } from "react"; class App extends Component { constructor(props) { super(props) } state = { fonSize: 12, width: 200} onChange1 = e => { this.setState({ fonSize: e }) } onChange2 = e => { this.setState({ width: e }) } render() { return ( <div> <Counter value={this.state.fonSize} onChange={this.onChange1} /> <Counter value={this.state.width} onChange={this.onChange2} setup={5}/> <div style={{ fontSize: this.state.fonSize }}> <span>文字大小</span> </div> <div style={{ width: this.state.width, border: '1px solid red' }}> <span>宽度</span> </div> </div> ) } } export default App;
2,子组件
//用prpps来接收 import React,{Component} from "react"; class Counter extends Component{ //constructor构造函数 Super调用父类的构造函数 constructor(props){ super(props) } setNum(n){ this.setState({num:n},()=>{ this.props.onChange(this.state.num) }) } state = { num :this.props.value, max: 800, min: 0 ,all:5} render(){ return( <div> <button onClick={()=>{if(this.state.num>this.state.min){this.setNum(this.state.num-this.props.setup)}}}>-</button> <input value={this.state.num} onChange={(e)=>{this.setNum(Number(e.target.value))}}/> <button onClick={()=>{if(this.state.num<this.state.max){this.setNum(this.state.num+this.props.setup)}}}>+</button> </div> ) } } export default Counter; //props单词固定写法,父组件传递给子组件的参数 //props里面的属性和方法都必须是只读(不可以更改其值) //定义默认props //父子传参:props //子父传参:子组件执行props的回调函数实现 Counter.defaultProps ={ value:1, max:Infinity, min:-Infinity, setup:1 } //默认props Counter.defaultProps ={} //Infinity无限
11生命周期
import List from './component/Life' import React, { Component } from "react"; class App extends Component { constructor(props) { super(props) console.log('第一阶段-创建阶段',); } state = { fonSize: 12, width: 200 } static getDerivedStateFromProps(nextProps, prevState) { console.log('第二阶段-创建阶段,getDerivedStateFromProps'); console.log(nextProps, prevState); console.log('第一阶段-更新阶段,getDerivedStateFromProps'); return prevState } shouldComponentUpdate(){ console.log('第二阶段-更新阶段,shouldComponentUpdate'); } render() { console.log('第三阶段-创建阶段,render'); console.log('第三阶段-更新阶段,render'); return ( <div> <h1>生命周期</h1> <List value={this.state.fonSize} /> </div> ) } componentDidMount() { console.log('第四阶段-创建阶段,componentDidMount'); } getSnapshotBeforeUpdate(prevProps,prevState){ console.log('第四阶段-更新阶段,getSnapshotBeforeUpdate'); return {name:'莫',age:15} } componentDidUpdate(snap){ console.log('第五阶段-更新阶段,componentDidUpdate,',snap); } } export default App;
创建阶段
01 counstuctor构造函数作用:初始化state
02 static getDerivedStateFromProps(nextProps,prevState)props更新nextProps最新的props,prevState之前State需要返回最新的State,父组件props更新组件的state作用:监听props变化
03 render渲染创建虚拟dom 作用:
04 componentDidMount组件挂载完毕作用: ajax,定时器,事件监听,操作dom(需要背诵)
更新阶段
01 static getDerivedStateFromProps父组件props更新组件的state 作用:监听props变化
02 shouldComponentUpdate(nextProps, nextState) 组件是否需委更新,返回true更新,返回false不更新作用:优化〔需要背诵)
03 render
04 getsnapshotBeforeUpdate(prevProps, prevState)更新前获取快照
05 componentDidUpdate组件已经更新完毕
卸载阶段
componentWillUnmount 组件将要卸载 作用:移除事件监听,停止定时器
12Hooks
1,useState
//useState是一个普通普通方法,执行后返回一个数组,第一值是状态,第二个是更新状态的方法5 是状态num的默认值 const [num,setnum]=useState(6)
2.useEffect:使用副作用
//模拟挂载完毕 useEffect(()=>{ }) //模拟卸载前 useEffect(()=>{ return()=>{} },[]) //监听莫个数据(count)的更新 useEffect(()=>{ //count更新前 return()=>{//count更新后} },[count]) //副作用中的函数访问的useState的值是默认值,如果使用第二个参数[count],访问的值是count更新后的的最新值
3:useRef:使用dom引用
import { useRef } from "react" function App (){ const myref = useRef() return( <div> <input ref = {myref} /> </div> ) } //myref.current.value访问input的值
4:自定义hooks
本质上普通的函数结合hooks返回一些可以用的数据
13:router-路由
1.概念
监听地址栏变化,不刷新页面,动态切换div模拟切换页面
2.安装
npm i react-router-dom -S
x
3.使用
import HomeView from "../component/HomeView"; import Aboutview from "../component/Aboutview"; import { useRoutes } from "react-router-dom"; const routes = [ { path: '/', element: <HomeView/> }, { path: '/about', element: <Aboutview/> } ] export default function RouterView(){ //创建路由 const elem = useRoutes(routes) //返回路由视图 return elem }
import { HashRouter as Router, NavLink } from 'react-router-dom'; import RouterView from './router' function App() { return ( <Router> <NavLink to='/'>首页</NavLink> | <NavLink to='./about'>关于</NavLink> <RouterView></RouterView> </Router> ) } export default App;
4,路由的组件也方法
//哈希路由 <HashRouter></HashRouter> //浏览器路由 <BrowserRouter></BrowserRouter> //导航链接 <NavLink></NavLink> //子路由容器 <Outlet></Outlet>
5,路由传参
import { useParams } from "react-router-dom" function ProductView() { //路由参数 const { id } = useParams() return ( <div>{id}</div> ) } export default ProductView
import { useSearchParams } from "react-router-dom" function ParamaView(){ //查询参数 const [searchParams] = useSearchParams() const text = searchParams.get('text') return( <div> ParamaView{text} </div> ) } export default ParamaView
import ProductView from "../view/ProductView" import ParamaView from "../view/ParamsView" const routes = [ { path: '/product/:id', element: <ProductView /> }, { path: '/params', element: <ParamaView /> } ] export default function RouterView() { //创建路由 const elem = useRoutes(routes) //返回路由视图 return elem }
import { HashRouter as Router, NavLink } from 'react-router-dom'; import RouterView from './router' function App() { return ( <Router> {/*方法1*/} <NavLink to='/product/666'>产品</NavLink> | {/*方法2*/} <NavLink to='./params?text=莫峰阁'>关于</NavLink>| </Router> ) } export default App;
6.子路由
{ path: '/admin', element: <AdminView /> , children:[ {path:'',element:<DashView/>}, {path:'orderlist',element:<OrderList/>} ] }
import { Outlet,Link } from "react-router-dom" function AdminView(){ return( <div> <h1>管理页面</h1> <Link to=''>概论</Link> | <Link to='orderlist'>订单</Link> {/*Outlet子组件容器*/} <Outlet/> </div> ) } export default AdminView
7.404页面
//配置在最后面 {path:"*",element:<div>404</div>}
8.权限组件
import { Navigate } from "react-router-dom"; function Private(props){ if(localStorage.getItem('token')){ return<>{props.children}</> }else{ return<Navigate to='/'></Navigate> } } export default Private
//权限组件 import Private from "./Private" const routes = [ { path: '/admin', element: <Private><AdminView /></Private>, children:[ {path:'',element:<DashView/>}, {path:'orderlist',element:<OrderList/>} ] }, {path:'/homereact',element:<HomeReact/>}, {path:'*',element:<NoMathch />} ] export default function RouterView() { //创建路由 const elem = useRoutes(routes) //返回路由视图 return elem }
9.懒加载组件
import {lazy,Suspense} from 'react' function LazyLoad(url){ const Element = lazy(()=>import('../view/'+url)) return <Suspense fallback={<h3>加载中...</h3>}> <Element/> </Suspense> } export default LazyLoad
14.@别名
//导入path import path from 'path' export default defineConfig({ plugins: [react()], resolve:{ alias:{ //@表示src目录 '@':path.relative(__dirname,'src') } } })