React
React 是什么?
React是一个简单的javascript UI库,用于构建高效、快速的用户界面。它是一个轻量级库,因此很受欢迎。它遵循组件设计模式、声明式 编程范式 和 函数式编程 概念,以使前端应用程序更高效。它使用虚拟DOM来有效地操作DOM。它遵循从高阶组件到低阶组件的单向数据流。
命令式编程 和 声明式编程
声明式编程: 是一种编程范式,它关注的是你要做什么,而不是如何做。它表达逻辑而不显式地定义步骤。这意味着我们需要根据逻辑的计算来声明要显示的组件。它没有描述控制流步骤。声明式编程的例子有HTML、SQL等
命令式编程:声明式编程的编写方式描述了应该做什么,而命令式编程描述了如何做。在声明式编程中,让编译器决定如何做事情。声明性程序很容易推理,因为代码本身描述了它在做什么。
简单来说就是:
告诉计算机怎么做(How) - 过程
告诉计算机我们要什么(What) - 结果
React的基本使用
1.初始React
代码:
<body>
<div id="root"></div>
<script>
/*
React.js 提供 核心代码
ReactDOM 提供了与浏览器交互的DOM功能: 如 虚拟DOM
ReactDOM.render(element, container[, callback])
element:要渲染的内容
container:要渲染的内容存放容器
callback:渲染后的回调函数
*/
ReactDOM.render(
'今天天气有点阴',
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
</body>
效果:
2.利用React创建试图
代码:
<body>
<div id="root"></div>
<script>
/*
React.js 提供 核心代码
ReactDOM 提供了与浏览器交互的DOM功能: 如 虚拟DOM
ReactDOM.render(element, container[, callback])
element:要渲染的内容
container:要渲染的内容存放容器
callback:渲染后的回调函数
React.createElement(type,props,children)
第一个参数是必填,传入的是似HTML标签名称,如: ul, li
第二个参数是选填,表示的是属性,如: className
第三个参数是选填,子节点,如: 要显示的文本内容
*/
let h1 = React.createElement('h1',null,'我是一个react标题')
let p = React.createElement('p',null,'我是一个react段落标签')
let el = React.createElement(
"header",
{id:"header"},
h1,p
)
ReactDOM.render(
el,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
效果:
3.React的JSX
代码:
<body>
<div id="root"></div>
<script type="text/babel">
/*
JSX: 基于 javascript 和 XML 的扩展语法
注意:要在 script 标签上写 type="babel" 来解析XML语言
*/
ReactDOM.render(
<header>
<h1>hello react</h1>
<p>利用JSX来渲染数据</p>
</header>,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
</body>
效果:
4.差值表达式
代码:
<body>
<div id="root"></div>
<script type="text/babel">
/*
JSX: 基于 javascript 和 XML 的扩展语法
*/
// 各种数据的插值状态
// let data = '天气还不错' // 原样输出
// let data = 1 // 原样输出
// let data = false // 不输出
// let data = undefined // 不输出
// let data = null // 不输出
// let data = ['内容1','内容2','内容3'] // 去掉逗号原样输出
let data = { // 直接使用不可输出, 要使用点的方式来使用
name:'大大大', // data.name data.age
age:18
}
let str = "今天天气不怎么样"
ReactDOM.render(
<header>
<h1>{data.name}</h1>
<h1>{data.age}</h1>
<h1>hello react {str}</h1>
<p>利用JSX来渲染数据</p>
</header>,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
</body>
效果:
5.条件输出
代码:
<body>
<div id="root"></div>
<script type="text/babel">
// 条件输出
// ? : 类似 if..else
// || 类似 if(!) 取反
// && 类似 if()
ReactDOM.render(
<header>
<h1>{false ? '成立' : '不成立'}</h1>
<h1>{true || '正确'}</h1> {/*短路效果*/}
<h1>{true && '错误'}</h1> {/*短路效果*/}
</header>,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
</body>
效果:
6.列表循环
代码:
<body>
<div id="root"></div>
<script type="text/babel">
let data = [
"内容1",
"内容2",
"内容3"
]
// 第一种方式
// function todata(){
// let arr = []
// data.forEach(item =>{
// arr.push(<li>{item}</li>)
// })
// return arr
// }
ReactDOM.render(
<ul>
{/*todata()*/}
{/*第二种方式*/}
{
data.map(item=>{
return <li>{item}</li>
})
}
</ul>,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
</body>
效果:
7.JSX注意事项
代码:
<body>
<div id="root"></div>
<script type="text/babel">
/*
JSX:
基于 javaScript 和XML 的扩展语法
它可以作为值使用
它并不是字符串
它也不是html
它可以配合js 表达式一起使用
它不可以和JS语句一起使用
所有的标签名必须是小写
所有的标签必须闭合,哪怕单标签
class 要写做 className
style 接收的是一个对象,并不是字符串
每次只能输出一个标签(或者说必须要有一个容器)
唯一父级 唯一容器
*/
let style = {
width:'600px',
height:'200px',
backgroundColor:'red'
}
let {Fragment} = React;
ReactDOM.render(
// <div>
// <div className="box" style={ {width: '100%', height: '100px'} }></div>
// </div>,
<Fragment>
<div className="box" style={style}></div>
</Fragment>,
document.querySelector('#root'),
()=>{
console.log('成功渲染在页面上')
}
)
</script>
<style>
.box{
width:200px;
height:200px;
background-color:aqua;
}
</style>
</body>
效果:
基于自动化的集成环境模式 - create-react-app - 脚手架
介绍
通过前面 script 的方式虽然也能完成 React.js 的开发,但是有一个现在前端很重要的特性 - 模块化,无法使用。
Create React App 是一个使用 Node.js 编写的命令行工具,通过它可以帮助我们快速生成 React.js 项目,并内置了 Babel、Webpack 等工具帮助我们实现 ES6+ 解析、模块化解析打包,也就是通过它,我们可以使用 模块化 以及 ES6+ 等更新的一些特性。同时它还内置 ESLint 语法检测工具、Jest 单元测试工具。还有一个基于 Node.js 的 WebServer 帮助我们更好的在本地预览应用,其实还有更多。
这些都通过 Create React App 帮助我们安装并配置好了,开箱即用
安装与使用
通过 npm、yarn、npx 都可以
npm i -g create-react-app
yarn global add create-react-app
安装完成以后,即可使用 create-react-app 命令
create-react-app <项目名称>
或者通过 npx 的方式
npx create-react-app <项目名称>
项目目录结构说明
运行命令以后,就会在运行命令所在目录下面创建一个以项目名称为名的目录
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
关于其他的一些命令(如: 启动, 打包命令)请进入 package.json 文件进行查看
React组件案例实例
创建一个新的 FriendList.js 文件
// FriendList.js 文件
import React,{Component} from 'react';
import './FriendList.css' // 引入样式文件
class FriendList extends Component {
render(){
return (
<div className="friend-list">
<div className="friend-group">
<dt>家人</dt>
<dd>爸爸</dd>
<dd>妈妈</dd>
</div>
<div className="friend-group">
<dt>朋友</dt>
<dd>张三</dd>
<dd>李四</dd>
<dd>王五</dd>
</div>
<div className="friend-group">
<dt>客户</dt>
<dd>阿里</dd>
<dd>腾讯</dd>
<dd>头条</dd>
</div>
</div>
)
}
}
export default FriendList // 向外暴露文件
创建一个新的 FriendList.css 文件
.friend-list {
border: 1px solid #000000;
width: 200px;
}
.friend-group dt {
padding: 10px;
background-color: rgb(64, 158, 255);
font-weight: bold;
}
.friend-group dd {
padding: 10px;
/* display: none; */
}
.friend-group.expanded dd {
display: block;
}
.friend-group dd.checked {
background: green;
}
最后在 App.js 文件中类显示到页面上
import React,{Component} from 'react';
import FriendList from './FriendList'
/*
类组件:
1.组件类必须继承 React.Component
2.组件类必须有 render 方法
3.在render方法中的return 里面定义组件的内容
注意:记得导出模块
*/
class App extends Component {
render() {
return (<div>
<FriendList />
</div>)
}
}
export default App;
效果:
组件复用 - 数据抽取(优化案例)
为了提高组件的复用性,通常会把组件中的一些可变数据提取出来
创建一个新的 data.js 文件,把抽离的数据放入其中
let datas = {
family: {
title: '家人',
list: [
{name: '爸爸'},
{name: '妈妈'},
{name: '儿子'}
]
},
friend: {
title: '朋友',
list: [
{name: '张三'},
{name: '李四'},
{name: '王五'},
{name: '赵六'}
]
},
customer: {
title: '客户',
list: [
{name: '阿里'},
{name: '腾讯'},
{name: '头条'}
]
}
};
export default datas
在 FriendList.css 文件中创建循环,先循环输出外面一层, 然后把数据发给 dl.js
import React,{Component} from 'react';
import './FriendList.css'
import Dl from './dl'
import data from './data'
class FriendList extends Component {
render(){
return (
<div className="friend-list">
{
Object.keys(data).map((item,index) => {
return (
<Dl
key = {index}
name = {item}
value = {data[item]}
/>
)
})
}
</div>
)
}
}
export default FriendList
最后在dl.js 文件中接收遍历数据,然后渲染出来
import React,{Component} from 'react';
class Dl extends Component {
render(){
let {title,list} = this.props.value;
return (
<div className="friend-group">
<dt>{title}</dt>
{
list.map((item,index) =>{
return <dd key={index}> {item.name} </dd>
})
}
</div>
)
}
}
export default Dl
效果:
React的事件
代码:
class App extends Component {
state = {
num:20,
name:'叮当猫',
sex:'蓝胖子'
}
// 类试组件中定义 constructor 一定需要接收 props, 调用 super()
// constructor(props){
// super(props);
// this.state = {
// num:0
// }
// }
// Fn = () =>{
// // console.log(this) // 可以使用箭头函数的方式来获取到 this
// this.setState({
// num:this.num+1
// })
// }
render() {
let {num} = this.state;
return (
<div>
{/*<p>{num}</p>*/}
<p>{this.state.num}</p>
<p>{this.state.sex}</p>
<p>{this.state.name}</p>
<button onClick={()=>{
this.setState({
num:num+1,
sex:'可爱的蓝胖子'
})
}}>
长一岁
</button>
</div>
)
}
}
效果:
React的案例(使用事件(优化案例)
只需要改动 dl.js 文件中的代码就可以了
import React,{Component} from 'react';
class Dl extends Component {
state = {
isOpen:false
}
render(){
let {title,list} = this.props.value;
let {isOpen} = this.state;
return (
<div className={"friend-group " + (isOpen ? "expanded" : "")}> {/*这里需要加空格*/}
<dt
onClick={()=>{
this.setState({isOpen:!isOpen})
}}
>{title}</dt>
{
list.map((item,index) =>{
return <dd key={index}> {item.name} </dd>
})
}
</div>
)
}
}
export default Dl
效果:
注意
1.注意:JSX是基于 javascript 和 XML 的扩展语法
2.注意:要在 script 标签上写 type=“babel” 来解析XML语言