|
目录
React
CDN引入
开发版本
压缩版本(生产环境)?
React.createElement(str,obj,innerHTML)
ReactDOM.render(h3,ele)
JSX
?使用
注释
数组
内联渲染样式
脚手架
创建项目包
安装VScode插件?
JSX?提示
类组件
接收参数
state状态
setState(state,callback)
defaultProps?
this.forceUpdate(callback)
函数组件
接收参数?
注意点?
事件
绑定this
bind绑定this
箭头函数绑定this
事件池
Hooks
Ref使用详解
React生命周期和错误处理方法
注意点?
img标签
React
react项目是SPA(Single web Page Application单页网页应用)项目,整个网站只有一个页面,通过路由切换页面中局部的内容,实现页面的变更。
CDN引入
注意下面引入的2个文件,React负责创建元素,ReactDom负责渲染元素到其它元素中。
开发版本
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
压缩版本(生产环境)?
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
?
React.createElement(str,obj,innerHTML)
利用React创建元素,其中str为标签的名,obj对象上的属性为该标签上挂载的属性,innerHTML为标签内的文本内容。
let h3 = React.createElement('h3',{id:'time',className:'danger'},'时间')
?
ReactDOM.render(h3,ele)
其中h3为上面React.createElement的返回变量,ele为dom节点。
下面利用ReactDOM渲染h3元素到id为‘yf’的节点上。
let ele = document.getElementById('yf')
ReactDOM.render(h3,ele)
?
JSX
使用前需要引入babel(使用脚手架创建会都生成好)。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
?再添加babel编译(使用脚手架创建会都生成好)。
<script type="text/babel">
?使用
可以理解为用于简化React.createElements函数。
const element = <h1 className = {'hello'}>Hello, world!</h1>;
?相当于
let element = React.createElement('h1',{className:'hello'},'Hello, world!')
?注意在JSX中一层大括号相当于引用js的环境,和vue中的双重大括号相同。
注释
通过一对大括号加/* */注释。
{/* 注释 */}
数组
数组中的JSX元素必须带唯一标识key,并且可以直接渲染数组。
let ele = [<li>1</li>,<li>2</li>,<li>3</li>]
ele.forEach((v,i)=>{v.key=i})//每个元素添加唯一的key
class list extends React.Component {
render() {
return (
<ul>{ele}</ul>
)
}
}
// 渲染为
// <ul>
// <li>1</li>
// <li>2</li>
// <li>3</li>
// </ul>
内联渲染样式
相当于直接给style赋值一个对象,对象中的属性为css样式,小驼峰形式不加横线。
<div style={{ color: 'red', fontSize: '16px' }}></div>
?
脚手架
要求Node>=8.1和npm>=5.6。
npm i -g create-react-app
创建项目包
?注意项目名需要小写,下面react-app为项目名。
create-react-app react-app
安装VScode插件?

安装后输入rcc可以自动生成类组件。
JSX?提示
js文件默认是只有js文件提示,想要有JSX文件提示需要像下方一样选中。

类组件
类名需要是大驼峰。类组件要求必须继承父类React.Component。
class HelloWorld extends React.Component {
render(){
return <h1>Hello World!</h1> //React.createDOM('h1',{},Hello World!') 也行
}
}
<HelloWorld /> //使用方式
接收参数
class HelloWorld extends React.Component {
constructor(props){
this.props = props //可以不用写,在父类中实现了
}
render(){
return <h1>Hello World!</h1> //React.createDOM('h1',{},Hello World!') 也行
}
}
new HelloWorld({name:'yf'}) //等同于<HellorWorl name='yf' />
则类中this.props.name等于'yf'?。
state状态
React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
?注意状态的修改和vue中的不同(vue中会自动重新渲染),react只有通过setState函数设置状态才会重新渲染。因为是重新渲染,故可以通过setState传入空对象,让之前直接通过this.state更改的状态生效。
setState(state,callback)
对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。state是需要合并的对象(注意相当于Object.assign,不是替换),callback是state更新完后的回调函数(建议使用?componentDidUpdate替代)。当需要使用到props和state时,state可以为一个函数例如下面,函数的返回对象为需要合并的对象。
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
注意在调用 setState() 后立即读取 this.state的值不一定会改变。?例如下面state.counter的值始终是不会变的。
this.setState({counter: state.counter++});
相当于?this.setState({counter: state.counter})先执行,再执行this.counter=this.counter+1两行代码,由于this.setState是异步的,所以每次都会将值重置。
defaultProps?
defaultProps?可以为 Class 组件添加默认 props。这一般用于 props 未赋值,但又不能为?null?的情况。例如:
class CustomButton extends React.Component {
// ...
}
CustomButton.defaultProps = {
color: 'blue'
};
如果未提供?props.color,则默认设置为?'blue'
render() {
return <CustomButton /> ; // props.color 将设置为 'blue'
}
如果?props.color?被设置为?null,则它将保持为?null
render() {
return <CustomButton color={null} /> ; // props.color 将保持是 null
}
this.forceUpdate(callback)
强制让组件重新渲染,callback为重新渲染后的回调函数。
函数组件
函数名要大驼峰写法。返回React.createElements生成的对象。
function HelloWorld(){
return <h1>Hello World!</h1> //React.createDOM('h1',{},Hello World!') 也行
}
<HelloWorld /> //使用方式
接收参数?
函数组件中可以接收一个参数,该参数为一个对象,属性为组件使用时上面的属性。
function HelloWorld(props){
return <h1>Hello World!</h1> //React.createDOM('h1',{},Hello World!') 也行
}
HelloName({name:'yf'}) //等同于<HellorWorl name='yf' />
?则props.name等于'yf'
?
注意点?
函数组件里面不要直接写setInterval和useState中设置state值的函数,这会导致定时器越来越多,和组件不停被重新渲染。
例如下面会产生setIterval(()=>{setCount(1)})、setIterval(()=>{setCount(2)})、3、4、5...等越来越多定时器。
function Counter() {
const [count, setCount] = useState(0);
setInterval(() => {
setCount(count + 1);
}, 1000);
// 造成的后果就是能一直更新count,但是每一轮循环都会执行上面这行代码,
//定时器越来越多,然后,就卡死啦,而且每个定时器都会执行一遍,
//那么屏幕上的数字每秒都会在跳,可以试试看
return <h1>{count}</h1>;
}
?
事件
标签上添加on事件名=‘方法名’来绑定事件。
注意事件名大写,绑定时不能在函数后加括号,加了会在创建时执行,触发指定事件时不会被执行。
绑定this
类组件中使用this需要注意this的指向,因为事件的触发都是window,this指向的是事件的调用者,故为window,所以使用时需要绑定this指向。
bind绑定this
下面可以在constructor中绑定this也可以在render中绑定this。
class Demo extends React.Component {
constructor(){
//super(props);
//this.show = this.show.bind(this);
}
show(){
console.log('点击')
}
render(){
return <button onClick={ this.show.bind(this) }>点击事件</button>
}
}
箭头函数绑定this
class Demo extends React.Component {
show(){
console.log('点击')
}
render(){
return <button onClick={ ()=>{ this.show() }}>点击事件</button>
}
}
事件池
React对事件对象进行了包装,对象会被放入池中统一管理。这意味着包装的事件对象可以被复用,当所有事件处理函数被调用之后,其所有属性都会被置空。React17开始移除了该特性。
例如下面代码e为undefined,会报错
function handleChange(e) {
// This won't work because the event object gets reused.
setTimeout(() => {
console.log(e.target.value); // Too late!
}, 100);
}
如果你需要在事件处理函数运行之后获取事件对象的属性,你需要调用?e.persist():
function handleChange(e) {
// Prevents React from resetting its properties:
e.persist();
setTimeout(() => {
console.log(e.target.value); // Works
}, 100);
}
?
Hooks
React中Hooks详解(useState、useEffect、useContext、useRef详解)_AIWWY的博客-CSDN博客
Ref使用详解
https://blog.csdn.net/AIWWY/article/details/123404928
React生命周期和错误处理方法
https://blog.csdn.net/AIWWY/article/details/123338490
注意点?
img标签
注意webpack打包工具要求本地图片使用require来引入,vue会自动生成,而react没有做处理,所以需要使用require引入。
<img src={ require(url) }>
|