React-study
前言
纯属当成笔记在记录每天晚上回来的所学
react代码编写注意地方
1.任何需要写js代码的地方都必须要写在{}里面,包括注释都是的
2.同一级别下 必须要有一个根元素包裹 类似于Vue的template下的第一个div
3.render函数最好写上()
4.写在html中的变量必须都是在this.state上定义过的
5.有状态的组件必须调用super()函数继承React.Components
6.修改页面上的数据必须要通过this.setState的形式去触发diff算法更新页面,类似于小程序的setData
1. react的安装
cnpm install -g create-react-app
create-react-app react-demo
cd react-demo
yarn start
默认启用的是npm,下载项目特别慢 切换淘宝镜像即可
2. vscode对jsx代码的支持
打开设置文件-> 首选项-> 设置->用户->文本编辑器->文件 加上*.js javascriptreact
参考博客:https://blog.csdn.net/qq_38845858/article/details/104878454
3.react-study
3.1 JSX
3.1.1 jsx语法
3.1.2 让jsx支持输入html标签
在需要输入html标签的地方使用 dangerouslySetInnerHTML 这个属性来指定对于的html标签变量
var html=<div>"html标签"</div>;
<div dangerouslySetInnerHTML ={{__html:html}></div>
3.2 ref的使用
用来获取当前页面上的某个元素
Vue:this.$refs.xxx的形式
React:this.refs.xxx
class App extends React.Component {
componentDidMount(){
console.log(this.refs['mydiv']); // <div>我是一个div</div>
}
render() {
var html="html标签";
return (
我是一个div
);
}
}
3. 虚拟DOM的使用
由于ref只能获取当前页面中元素,但是如果想要获取子组件中的某个元素的话 ,可以采用dom的形式进行获取,但是这种形式React是不推荐的 ,因为非常的消耗性能,所以就有了虚拟DOM的概念
import ReactDOM from 'react-dom'
ReactDOM.findDomNode()
App.js
let heads = ReactDOM.findDOMNode(document.getElementById('header'))
console.log(heads) // <div id="header"></div>
header.jsx
import React from "react";
class Header extends React.Component{
render(){
return (
<div id="header"></div>
)
}
}
export default Header;
3.1 虚拟DOM原理
4.手写jsx实现虚拟DOM
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no"/>
<title>jsx实现虚拟dom</title>
</head>
<body>
<script src="js/babel.min.js"></script>
<script type="text/babel">
/*@jsx createElement*/ //@jsx babel的自执行指令
let users=[
{name:"张三"},
{name:"李四"},
{name:"王五"}
];
let vDom=(<div id="app" name="app">
hello world!
<ul>
{
users.map((item,index)=>{
return (
<li key={index}>{item.name}</li>
)
})
}
</ul>
</div>);
// let vDom=("hello world! ");
/*
将真实的dom转成虚拟dom,json格式开销小,性能高
{
nodeName:div,
attr:{
id:"app"
},
children:["hello world!"]
}
*/
function createElement(nodeName,attr,...args){
return {nodeName:nodeName,attr:attr,children:[].concat(...args)}
}
// 通过render将虚拟Dom生成真实的DOM元素
function render(vnode){
// 首先先对传进来的虚拟DOM 进行createElement处理 转成js
console.log(vnode.split)
// 判断是不是文本 只有文本才有字符串的split方法
if(vnode.split){
// 如果是文本 直接创建文本节点
return document.createTextNode(vnode);
}
// 如果不是文本
// 拿到标签名创建标签
let node=document.createElement(vnode.nodeName);
// 为创建的标签添加属性
let attr=vnode.attr || {};
Object.keys(attr).forEach((k)=>{
node.setAttribute(k,attr[k]);
});
//添加子节点
(vnode.children || []).forEach((n)=>{
node.appendChild(render(n))
});
return node;
}
let dom=render(vDom);
// 将生成的dom元素追加到页面中去
document.body.appendChild(dom);
</script>
</body>
</html>
5 .条件渲染 列表循环 事件处理
5.1 条件渲染
写法1:
var box;
if(this.state.isShow){
box=我是isShow渲染的
}
写法2:
{this.state.isShow&&<div>我是一个h1</div>}
列表渲染
列表渲染必须要指定一个key,使得React进行高效的更新
{this.state.goodsList.map((ele,index)=>{
return (
{ele.name}
)
})}
Class 与 Style写法
class写法
由于react对原始的dom进行了重写,所以在react中式没有class的,而是通过className来绑定类名的。
对于style写法需要两个{{}},可以这么理解 因为jsx语法,随意任何的js代码都需要写在{},包括之前的括号,所以第一个{}代表这里写js的代码,第二个则是一个style样式对象。
<div className = "box" style={{opacity:1}}></div>
class与style的动态写法
<div className={1>3?"":"active"} style={{backgroundColor:1>5?"red":"blue",opacity:1}}>
</div>
父组件向子组件传值
和微信小程序Vue一样 都是通过属性的形式传递参数。
在子组件中通过 this.props.xxx的形式进行访问;
使用propTypes进行类型的校验
对父组件传递过来的数据进类型的校验
import propTypes from 'prop-types‘
语法:类名.propTypes = {
传递过来的数据:propTypes .string.isRequired
}
通过defaultProps指定默认值
类名.defaultProps = {
传递过来的数据:默认值1
}
React的事件
react绑定事件采用的是驼峰命名法,它对原生的onclick方法进行了一次的重写
绑定事件的两种方式:
es5的写法
onClick = {this.clickHandle.bind(this)}
es6的写法:
onClick = {(e)=>{this.clickHandle(e)}}
事件的处理函数写在和render函数同级下即可
区别在于 es5的写法的传参数存在问题 而且es5的写法需要使用到bind来改变作用域,因为clickHandle这个函数是在组件里面的 我们需要将我们绑定的事件处理函数指向我们当前的组件,这样绑定的事件才能访问到这个函数。但是如果通过es6的写法就存在函数作用域的问题了。