一.React简介
1.1介绍
1.React是一个构建用户界面的JavaScript库; 2.React主要用于构建UI,很多人认为React是MVC中的V(视图); 3.React起源于Facebook的内部项目,用来架设Instagram的网站,并与2013年5月开源; 4.React拥有较高的性能,代码逻辑非常简单,越来越多的人已经开始关注和使用它。
1.2特点
现在看起来可能感受不是很明显~,等后期上了代码之后,一定要记得回头看哦
- 高效:React通过对DOM的模拟,最大限度地减少与DOM的交互;
- 灵活:React可以与已知的库或框架很好地配合;
- JSX:JSX是JavaScript语法的扩展。React开发不一定使用JSX,但我们建议使用它。
- 组件:通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
单向响应的数据流,React 实现了单向响应的数据流,从而减少了重复代码,这也是为什么比传统数据绑定更简单。
1.3框架对比
与其他框架的共同点都是,都采用虚拟DOM和数据驱动。
| angularJs | reactJs | vueJs |
---|
控制器 | √ | - | - | 过滤器 | √ | - | √ | 指令 | √ | - | √ | 模板语法 | √ | - | √ | 服务 | √ | - | - | 组件 | - | √ | √ | jsx | - | √ | 2.0之后加入 |
二.环境搭建
2.1引入文件的方式
1.React.js:React的核心库,解析组件,识别jsx。
https://cdn.staticfile.org/react/16.4.0/umd/react.development.js
2.reactDom.js:处理有dom相关的操作。
https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js
3.Babel.js:将 ES6 代码转为 ES5 代码。
https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js
2.2官方脚手架(模块化)
后期讲解。。。
三.HelloWorld
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="box">
</div>
</body>
</html>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('box')
);
</script>
ReactDOM.render( JSX写的html模板,dom容器对象); 总结:一个react的程序,就是把JSX通过ReactDOM.render()函数渲染到网页上。
注意:Script标签中的type取值为:text/babel。 总结: 1.一个react的程序,是通过jsx通过ReactDO.render()函数渲染到网页上。 2.React的代码也可以单独写在一个文件中,扩展名为js/jsx。引入时记住type="text/babel’。
四.JSX
4.1介绍
1.JSX是JavaScript xml,是JavaScript的语法扩展,只要HTML代码写在JS里,那就是JSX。JSX在打包阶段都已经编译成纯JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。
4.2特点
- JSX执行更快,因为它在编译为JavaScript代码后进行了优化;
- 它是类型安全的,在编译过程中就能发现错误;
- 使用JSX编写模板更加简单快速。
4.3语法
其实就是与原来HTML中的区别。话不多说,来段代码,让我瞧瞧有啥区别。。。
var msg="哥们!"
const element = <h1>Hello, world!{msg}</h1>
//没有双引号,不是字符串
const List = () => (
? <ul>
? <li >list item</li>
? <li>list item</li>
? <li>list item</li>
? </ul>
);
XML基本语法:
- 只能有一个根标签,养成外面加上圆括号的习惯(自行体会圆括号的作用哈,练得多了就有感jiao了)
- 标签要闭合(注意单标签)
4.1.1元素类型
- 小写首字母对应 HTML的标签,组件名首字母大写。
- 注释
①使用 /* 内容 */ ②html标签内注释{/*最外层有花括号*/}
4.1.2元素属性
- 内联样式的style:样式名以驼峰命名法表示。 默认像素单位是 px,则px不用写。
let _style = { backgroundColor:"red" };
ReactDOM.render(
<h1 style={_style}>Hello, world!</h1>,
document.getElementById('box')
);
- 外部样式的class:HTML中曾经的 class 属性改为 className(因为class是js的关键字),外部样式时使用
ReactDOM.render(
<h1 className="bluebg">Hello, world!</h1>,
document.getElementById('box')
);
4.1.3JavaScript表达式
- 使用单花括号。注意单花括号中只能写表达式,不能写语句。
const element = <h1>Hello, {120+130}!</h1>
const element = <h1>Hello, {getName("张三疯")}!</h1>
<input type="text" value={val ? val : ""} />
五.条件渲染
var age = 19;
if (age >= 18) {
var ageShow = <p>是否成年:已成年</p>;
} else {
var ageShow = <p>是否成年:未成年</p>;
};
function show(score) {
switch (true) {
case score<60: var str = <p>亲,您得享受免费重修的机会</p>
break;
case score>=60 && score<=70:var str = <p>亲,您学得挺好</p>
break;
case score>70 && score<=100:var str = <p>亲,您是学霸</p>
break;
default:
break;
}
return str;
}
ReactDOM.render(
<div>
<div>{ageShow}</div>
<div>{show(90)}</div>
</div>,
document.getElementById("box")
);
注:if语句不要写在单花括号里。
六.列表渲染
- 渲染数组:使用Javascript的map()或者普通for循环进行列表的渲染
// jsx的数组,可以直接渲染到页面上
var arr = [
<li>如何让富婆爱上我</li>,
<li>霸道总裁爱上我</li>,
<li>啦啦啦啦</li>,
];
function show(arr) {
// return arr.map(item=>{
// // 只有一行,则可以简写
// return (<li>{item}</li>)
// })
return arr.map((item) => <li>{item}</li>);
// 用普通的for循环实现
let jsxArr = [];
for (let i in arr) {
jsxArr.push(<li>{arr[i]}</li>);
}
}
ReactDOM.render(
<div>
<p>推荐给大家的书籍</p>
{/*有没有发现,竟然不用循环*/}
<ul>{arr}</ul>
</div>,
document.getElementById("box")
);
var scores = [98, 61, 85, 59, 50, 99, 85];
ReactDOM.render(
<div>
<h1>及格的成绩</h1>
<ol>
{scores
.filter((score) => score >= 60)
.map((item) => (
<li>{item}</li>
))}
</ol>
</div>,
document.getElementById("box")
);
var studens = [
{
id: "1001",
name: "张三",
project: "前端",
},
{
id: "1002",
name: "李四",
project: "JAVA开发",
},
{
id: "1003",
name: "王五",
project: "软件测试",
},
{
id: "1004",
name: "张三疯",
project: "后端开发",
},
];
ReactDOM.render(
<div>
<p>某班学生基本信息</p>
<ul>
{studens.map((item) => (
<li>
<p>学号:{item.id}</p>
<p>姓名:{item.name}</p>
<p>专业方向:{item.project}</p>
</li>
))}
</ul>
</div>,
document.getElementById("box");
);
七.组件
7.1单个组件
1.定义组件的三种方式:函数方式、ES5的写法、ES6(类)的写法。
// 定义组件,组件名首字母大写(大驼峰)
function MyCom(){
const msg="hello";
return (
<ul>
<li>{msg}:三国演义</li>
<li>{msg}:红楼梦</li>
</ul>
)
}
ReactDOM.render(
<MyCom/>,
document.getElementById('box')
);
- ES5的写法:React.CreateClass()函数(React16后,已经被废弃了)~作为了解
var MyCom = React.createClass({
render:function(){ //vue中也有render函数,是完成模板的代码
return (
<div>
<h1>Hello, world!</h1>
</div>
);
}
});
- ES6类的写法:定义一个类,继承自 React.Component,在该类里,必须有个render()函数,render函数返回一个JSX代码。
class MyCom extends React.Component {
constructor() {
// 调用父类的构造函数
super();
this.state = {
age: 12,
};
this.name = "哆啦A梦";
}
render() {
var msg = "hi";
return (
<div>
<p>{msg}:我还是个pp</p>
<p>年龄:{this.state.age}</p>
</div>
);
}
}
ReactDOM.render(
<div>
{new MyCom().render()}
<hr />
<MyCom />
</div>,
document.getElementById("box")
);
7.2组件嵌套
// 函数组件
function Books() {
var books = ["哆啦A梦", "皮卡丘"];
return (
<ul>
{/*
{books.map((book, i) => (
<li key={i}>{book}</li>
))}
*/}
{books.map((book) => (
<li>{book}</li>
))}
</ul>
);
}
// 类组件
class MyCom extends React.Component {
render() {
var msg = "hi";
return (
<div>
<p>{msg}</p>
<Books />
</div>
);
}
}
ReactDOM.render(
<div>{new MyCom().render()}</div>,
document.getElementById("box")
);
八.Props
还记得吗?vue中也有props吆~忘了的小伙伴,可以戳这儿
还有我呢~ props 是组件对外的接口。接收外部传入的数据。是组件的属性(等同于html标签的属性)。 注意:Props对于使用它的组件内部来说,是只读的。一旦赋值不能修改。
8.1外部传值:
<组件名 属性名1=值1 属性名2=值2 .. />
属性值=“静态值” 属性值={js数据}
8.2组件内部使用
1)函数组件:{props.属性名}
function Books(props) {
return (
<ul>
<li>书名:{props.name}</li>
<li>作者:{props.author}</li>
</ul>
);
}
ReactDOM.render(
<div>
<Books name="皮卡丘" author="me" />
</div>,
document.getElementById("box")
);
2)类组件:{this.props.属性名}
class Mycom extends React.Component{
constructor(props){
super();
}
render(){
return(
<ul>
<li>书名:{this.props.name}</li>
<li>作者:{this.props.author}</li>
</ul>
)
}
}
ReactDOM.render(
<div>
<Mycom name="皮卡丘" author="me" />
</div>,
document.getElementById("box")
);
答疑解惑~
补充:如果传递数据较多的话,可以使用对象,但是必须使用扩展运算符(…)
class MyPerson extends React.Component{
// constructor(props){
// super(props);
// }
render(){
return (
<div>
<p>{this.props.name}</p>
<p>{this.props.sex}</p>
</div>
)
}
}
let person={
name:"张三疯",
sex:"男"
}
ReactDOM.render(
<MyPerson {...person}/>,
document.getElementById('box')
);
8.3默认值
function Books(props){
return (
<ul>
<li>书名:{props.name||"哆啦A梦"} </li>
<li>价格:{props.price||"108"}</li>
</ul>
)
}
ReactDOM.render(
<div>
<Books name="你好啊"/>
</div>,document.getElementById("box")
)
2)、defaultProps
function Books(props){
return (
<ul>
<li>书名:{props.name}</li>
<li>作者:{props.price}</li></ul>
)
}
Books.defaultProps = {
name:"皮卡丘",
price:44
}
ReactDOM.render(
<div>
<Books name="你好啊"/>
</div>,document.getElementById("box")
)
1)、使用static修饰
class Books extends React.Component{
//类的属性用static修饰
static defaultProps={
name:"蓝胖子",
author:"不明"
}
render(){
return (
<ul>
<li>书名:{this.props.name}</li>
<li>作者:{this.props.author}</li>
</ul>
)
}
}
Books.defaultProps = {
name:"无书名",
author:"不详"
}
ReactDOM.render(
<div>
<Books name="你好啊"/>
</div>,document.getElementById("box")
)
2)、defaultProps
class Books extends React.Component{
render(){
return (
<ul>
<li>书名:{this.props.name}</li>
<li>作者:{this.props.author}</li>
</ul>
)
}
}
Books.defaultProps = {
name:"无书名",
author:"不详"
}
ReactDOM.render(
<div>
<Books name="你好啊"/>
</div>,document.getElementById("box")
)
函数式组件与类组件默认值的区别
格式:
//1)、函数式组件和类组件都可以:
组件名.defaultProps={
属性名: 默认值
}
//2)、若为类组件,可以在类的内部使用static修饰。
static defaultProps={
属性名: 默认值
}
8.4类型检查:
注意:react15.5后,React.propTypes已经移入到另外一个库里,请使用prop-types。
https://cdn.staticfile.org/prop-types/15.6.1/prop-types.js
//类型约定:
组件名.propTypes={
属性名1:PropTypes.类型名,
属性名2:PropTypes.类型名
}
//必传参数
propName: PropsTypes.类型名.isRequired
类型名的可以取值为:
PropTypes.array, PropTypes.bool, PropTypes.func, PropTypes.number, PropTypes.object, PropTypes.string, PropTypes.symbol,
如:
class Books extends React.Component {
render() {
return (
<ul>
<li>书名:{this.props.name}</li>
<li>作者:{this.props.author}</li>
<li>作者:{this.props.price}</li>
</ul>
);
}
}
Books.defaultProps = {
name: "无书名",
author: "不详",
};
// 注意大小写
Books.propTypes = {
name: PropTypes.string.isRequired,
author: PropTypes.string,
price: PropTypes.number,
};
ReactDOM.render(
<div>
{/*/因为number是数字,则用单花括号*/}
<Books name="你好啊" price={128} />
</div>,
document.getElementById("box")
);
九.state状态机
state 是状态,状态就是数据,state表示组件的内部数据。而props是外部传入组件的数据。
9.1定义并赋初始值
class App extends React.Component {
constructor(props){
super(props);
this.state={
//设置状态的初始值
属性名:属性值
}
}
}
9.2读取状态
this.state.属性名
9.3修改状态
必须调用setState()函数,不要直接赋值,而且,setState()函数是异步的。 ①修改状态时,必须要调用setState。因为,只要调用了setState函数,那就会调用了render()。如果直接赋值,不会把数据响应式地渲染到DOM上。(即:没有调render()函数)
class Books extends React.Component {
constructor(){
super();
this.state={
name:"情深深",
author:"琼瑶",
desc:{
beijing:"bj",
date:"shijian"
},
}
}
changeName(){
this.setState({
name:"皮卡丘"
})
}
changeDate(){
this.setState({
desc:{
...this.state.desc,date:(new Date()).toLocaleString()
}
})
}
render() {
return (
<ul>
<input type="button" value="修改name" onClick={()=>
this.changeName()
}/>
<input type="button" value="修改时间" onClick={()=>this.changeDate()} />
<li>书名:{this.state.name}</li>
<li>作者:{this.state.author}</li>
<li>背景:{this.state.desc.beijing}</li>
<li>时间:{this.state.desc.date}</li>
</ul>
);
}
}
ReactDOM.render(
<div>
<Books/>
</div>,
document.getElementById("box")
);
②setState()函数是异步的
class Books extends React.Component {
constructor() {
super();
this.state = {
name: "情深深",
author: "琼瑶",
};
}
// 改变状态之前做的事
// changeName() {
// this.setState(() => {
// console.log("改变状态之前做的事情");
// console.log("this.state.name", this.state.name);
// return {
// name: "hi",
// };
// });
// }
// // 改变状态之后做的事
// changeName(){
// console.log("改变状态之前做的事情");
// console.log("this.state.name", this.state.name);
// this.setState({
// name:"hi"
// },()=>{
// console.log("改变状态之后做的事情");
// console.log("this.state.name", this.state.name);
// })
// }
// 改变状态前后
changeName() {
this.setState(
function (prevState) {
console.log("判断函数有无参数arguments", arguments);
console.log("改变状态前想干的事情", prevState.name);
console.log("改变状态前想干的事情", this.state.name);
return {
name: "hi",
};
},
function () {
// 判断函数有无参数
console.log("判断函数有无参数arguments", arguments);
console.log("this.state.name", this.state.name);
}
);
}
render() {
return (
<ul>
<input
type="button"
value="修改name"
onClick={() => this.changeName()}
/>
<li>书名:{this.state.name}</li>
<li>作者:{this.state.author}</li>
</ul>
);
}
}
ReactDOM.render(
<div>
<Books />
</div>,
document.getElementById("box")
);
|