目录
React.createElement(str,obj,innerHTML)
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'
props.children
获取调用组件时填充到组件标签内部的内容,类似于vue中的slot插槽。
<Person>组件内部的内容</Person> const Person = (props) => { return ( <div>(props.children)</div> ); }
注意点
函数组件里面不要直接写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) }>
原文链接:https://blog.csdn.net/AIWWY/article/details/123327577?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165918321816781685358459%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165918321816781685358459&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-27-123327577-null-null.nonecase&utm_term=cdn
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/266