一、react基本了解
1.组件定义
React 组件是一段可以使用标签进行扩展 的 JavaScript 函数。每个 React 组件都是一个 JavaScript 函数,它会返回一些标签,React 会将这些标签渲染到浏览器上。React 组件使用一种被称为 JSX 的语法扩展来描述这些标签。JSX 看起来和 HTML 很像,但它的语法更加严格并且可以动态展示信息。了解这些区别最好的方式就是将一些 HTML 标签转化为 JSX 标签。
-
函数组件
export default function Demo(){return (<div>hello,react</div>) }
-
类组件
import React from 'react' export default class Demo extends React.Component{render(){return (<div>hello,react</div>)} }
使用html的cdn练习,后面使用脚手架
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>reactDemo</title><script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.24.8/babel.js"></script>
</head>
<body><div id="test"></div><script type="text/babel">class Demo extends React.Component{render(){return (<div>hello,react</div>)}}// 2.渲染虚拟DOM到页面ReactDOM.render(<Demo/>, document.getElementById('test'))</script>
</body>
</html>
2.组件创建
-
组件命名规范(jsx规范)
-
组件必须以大写字母开头,而 HTML 标签则必须是小写字母。
-
虚拟DOM元素只能有一个根元素 比如
<div>...</div>
或使用空的<>...</>
包裹 -
虚拟DOM元素必须有结束标签
function MyDemo(){return (<div>里面写html内容</div>) }
-
3.组件样式
-
使用class样式 使用className代替class名称
import React, { Component } from 'react' import './index.css' export default class extends Component {render() {return (<div className='title'>hello react</div>)} }
<!-- index.css --> .title{width:300px;height:30px;background-color:'red' }
-
使用style样式
style={{}}
,第一个{}表示接受的是一个对象,第二个{}表示读取引入的变量内容
import React, { Component } from 'react'export default class extends Component {render() {return (<div style={{width:'200px',height:'30px',backgroundColor:'red'}}>hello react</div>)} }
4.数据渲染
-
变量渲染 通过
{}
引用变量或者函数return (<h1>{user.name}</h1> );
-
条件渲染
import React, { Component } from 'react'export default class extends Component {isLogin=falserender() {if(this.isLogin){return (<div>已经登录了</div>)}else{return (<div>未登录,将返回登录页面</div>)}} }
-
列表渲染 使用数组的map方法
- key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
- key必须唯一
import React, { Component } from 'react'export default class extends Component {fruitArr=['西瓜','苹果','草莓']render() {return (<ul>{this.fruitArr.map((n,index)=>{return <li key={index}>{n}</li>})}</ul>)} }
5.事件绑定
import React, { Component } from 'react'export default class extends Component {handleClick=(e)=>{e.preventDefault(); //阻止事件默认效果alert('hello,world')}render() {return (<div><button onClick={this.handleClick}>点我弹框</button></div>)}
}
6.数据存储
state 状态记录器
组件内部重要的属性,取值是一个对象,存储组件的信息,案例如下:
- state:组件内部的属性,用于记录组件状态,取值是一个object
- setState:用于修改state的值,页面才会对应变化
//当前天气默认炎热 点击改变按钮 变成凉爽
import React, { Component } from 'react'
export default class Weather extends Component {//创建默认天气state={isHot:true}//改变天气changeTq=()=>{//只能通过setState来改变值,页面才会渲染变化的值this.setState({isHot:false})}render() {return (<div><p>当前天气:{this.state.isHot?'炎热':'凉爽'}</p><button onClick={this.changeTq}>改变天气</button></div>)}
}
props 属性收集器
记录每个组件标签属性对象,通常用于父组件给子组件传递数据。如下:App给Student传递数据
import Student from "./components/Student";
function App() {return (<div><Student name="夫子" age="96"/></div>);
}export default App;
import React, { Component } from 'react'
export default class Student extends Component {render() {return (<div><ul><li>姓名:{this.props.name}</li><li>年龄:{this.props.age}</li></ul></div>)}
}
对props
中的属性值进行类型限制和必要性限制:
安装prop-types
import PropTypes from 'prop-types';
使用PropTypes:
import React, { Component } from 'react'
import PropTypes from 'prop-types';
export default class Student extends Component {static propTypes={name:PropTypes.string.isRequired, //必须传入age:PropTypes.string}render() {return (<div><ul><li>姓名:{this.props.name}</li><li>年龄:{this.props.age}</li></ul></div>)}
}
refs 身份定义器
组件通过refs值来定义自己,相当于原生documen.getElementByxxx
-
字符串定义
//定义 <input ref="myInput"></input> //使用 this.refs.myInput.value
-
回调函数定义
//定义 <input ref={c=>this.myInput=c}></input> //使用 this.myInput.value
-
createRef方法定义
//定义 myInput=React.createRef() <input ref={this.myInput}></input>//使用 this.myInput.current.value
案例:点击按钮,显示输入框内容
import React, { Component } from 'react'export default class extends Component {
myInput=React.createRef()render() {return (<div><input ref={this.myInput}></input><button onClick={()=>alert(this.myInput.current.value)}>点我弹框</button></div>)}
}
7.生命周期
7.1 旧版本生命周期
- 初始化阶段
- constructor
- componentWillMount (将废弃)
- componentDidMount 比较常用: 一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
- 更新阶段
- shouldComponentUpdate 组件是否应该被更新(默认返回
true
) - componentWillUpdate (将废弃)
- render
- componentDidUpdate
- shouldComponentUpdate 组件是否应该被更新(默认返回
- 卸载阶段
- componentWillUnmount 关闭定时器
class LifeDemo extends React.Componet(){ //构造器 默认实例后就执行 【出生】constructor(){}//组件将要挂载前执行componentWillMount(){}//组件完成挂载执行(只执行一次)componentDidMount(){}//每次组件内容变了则会执行 1+n次render(){}//通常是父组件给子组件传递属性值,引发此函数顺序一系列执行//第一次传递的无效,后面的有效componentWillReceiveProps(){}//组件是否更新 默认为返回true 【组件的更新阀门(state状态变了,则执行)】// 如果写了,则必须返回true ,如果返回false,则state变了不会引入组件内容变化shouldComponentUpdate(){return true;}//组件将要更新前执行 forceUPdate也能导致此函数顺序一系列执行 componentWillUpdate(){}//组件完成更新后执行componentDidUpdate(){}//组件将要销毁执行 【死亡】componentWillUnmount(){}
}
- 更新说明:
7.2 新版本生命周期
- 初始化
- constructor
- getDerivedStateFromProps
- render :初始渲染dom数据
- componentDidMount :组件挂载dom执行一次 通常开启监听、发生请求
- 更新阶段 由组件this.setState或者组件重新render出发
- getSnapshotBeforeUpdate
- render
- componentDidUpdate
- 卸载阶段
- componentWillUnmount
- componentWillUnmount
class Life extends React.Component(){// 此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。//从Props获取一个派生的state 返回的值会更改已有的statestatic getDerivedStateFromProps(props,state){return props}render(){}compoentDidMount(){}// 组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()。getSnapshotBeforeUPdate(preProps,preState){return snapshotValue}componentDidUpdate(preProps,preState,snapshotValue){}}
getSnapshotBeforeUPdate
的使用案例:
每次添加新闻,保持滑动的那条新闻不随滚动条移动。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>reactDemo</title><script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.24.8/babel.js"></script><style>.list{width: 200px;height: 150px;background-color: aqua;overflow:auto;}.news{height: 30px;}</style>
</head>
<body><div id="test"></div><script type="text/babel">class MyLife extends React.Component{//初始化数据state={newArr:[]}componentDidMount(){console.log('dfdfd');this.timer=setInterval(()=>{let {newArr}=this.state//每次创建一条新闻let news="新闻"+(newArr.length+1)this.setState({newArr:[news,...newArr]})},1000)}stop=()=>{console.log("停了吗");clearInterval(this.timer)}getSnapshotBeforeUpdate(){console.log("getSnapshotBeforeUpdate....");return this.dd.scrollHeight}render(){return (<><div className="list" ref={c=>this.dd=c}>{this.state.newArr.map((n,index)=>{return <div key={index} className="news">{n}</div>})}</div><button onClick={this.stop}>stop</button></>);}componentDidUpdate(preProps,preState,height){console.log("componentDidUpdate...");console.log(this.dd,height);this.dd.scrollTop+=this.dd.scrollHeight-height}}// 2.渲染虚拟DOM到页面ReactDOM.render(<MyLife/>, document.getElementById('test'))</script>
</body>
</html>
8.快速demo(脚手架)
-
模块化,组件化:react+webpack+eslint+es6
-
快速构建一个简单的react项目
npx create-react-app react_demo
-
启动react项目
cd react_demo npm start Starting the development server...
9. 快速创建Hello组件
创建Hello组件
使用Hello组件
10 样式模块化
创建Welcome组件,设置class,但是Welcome组件没有css文件
import { render } from '@testing-library/react'
import react,{Component} from 'react'
export default class WelCome extends Component{render(){return (<div className='title'>hello welcome</div>)}
}
Hello组件的内容
import { render } from '@testing-library/react'
import react,{Component} from 'react'
//【引入目录下的css样式】
import './index.css'
export default class Hello extends Component{render(){return (<div className='title'>hello react</div>)}
}
App引入Welcome组件,这个时候Welcome被渲染的时候使用了Hello组件下的样式了。
import logo from './logo.svg';
//直接引入
import Hello from './components/Hello'
import Welcome from './components/Welcome'
function App() {return (<div><Hello/><Welcome/></div>);
}
export default App;
效果:
解决办法:
- 将
xxx.css
------>xxx.module.css
- 通过
import xxx from './xxx.module.css'
className={xxx.title}
<!--正常引入的css -->
.title{width: 300px;height: 30px;color: rgb(78, 78, 53);background-color: rgb(157, 110, 49);border: 2px solid #ccc;
}
<!-- 样式模块化后的css-->
.Hello_title__OTB7- {width: 300px;height: 30px;color: rgb(78, 78, 53);background-color: rgb(157, 110, 49);border: 2px solid #ccc;
}
11.插件安装
通过命令快速生成组件模式,如class模式组件,function模式组件
// 输入【rcc】(react class create)
import React, { Component } from 'react'export default class index extends Component {render() {return (<div>index</div>)}
}// 输入【rfc】(react function create)
import React from 'react'export default function index() {return (<div>index</div>)
}