文章目录
本文只介绍最基础的几个,如果有些东西没写到,那应该是被单独拆出去了,具体的可以去专栏查看:https://blog.csdn.net/qq_45677671/category_10940698.html
一、数据渲染
1.1、条件渲染
- 第一种写法
import React ,{Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component{
constructor(){
super();
this.state = {
like:true
}
}
render(){
let str = '';
// 三目运算符写法:
// str = this.state.like?'喜欢':'不喜欢';
// if else 写法:
if(this.state.like){
str = '喜欢'
}else{
str = '不喜欢'
}
return (
<div>
我{str}React
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
- 第二种写法
import React ,{Component} from 'react'
import ReactDOM from 'react-dom'
class App extends Component{
constructor(){
super();
this.state = {
like:true
}
}
render(){
// 三目运算符写法:
// return this.state.like?<div>我喜欢React</div>:<div>我不喜欢React</div>
// if else 写法:
if(this.state.like){
return (
<div>
我喜欢React
</div>
)
}else{
return (
<div>
我不喜欢React
</div>
)
}
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
1.2、列表渲染
React的高效依赖于所谓的 Virtual-DOM,尽量不碰 DOM。对于列表元素来说会有一个问题:元素可能会在一个列表中改变位置。要实现这个操作,只需要交换一下 DOM 位置就行了,但是React并不知道其实我们只是改变了元素的位置,所以它会重新渲染后面两个元素(再执行 Virtual-DOM ),这样会大大增加 DOM 操作。但如果给每个元素加上唯一的标识,React 就可以知道这两个元素只是交换了位置,这个标识就是
key
,这个key
必须是每个元素唯一的标识
- forEach 写法
import React ,{Component} from 'react';
import ReactDOM from 'react-dom';
class App extends Component{
constructor(){
super();
this.state = {
like:true,
}
}
//key 优化性能,key唯一表示一行。在做行的增加修改删除的时候,不需要遍历数组
render(){
const list = ["吃饭", "睡觉", "打豆豆"];
let arr = [];
// for(let i=0; i<list.length;i++){
// arr.push(<li key={i}>{list[i]}</li>)
// }
list.forEach((item,index)=>{
arr.push(<li key={index}>{item}</li>)
})
return (
<div><ul>{arr}</ul></div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
- map 写法
import React ,{Component} from 'react';
import ReactDOM from 'react-dom';
class App extends Component{
constructor(){
super();
this.state = {
like:true,
}
}
render(){
const list = ["吃饭", "睡觉", "打豆豆"];
return (
<div><ul>
{
list.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul></div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
- 循环的复杂写法
import React ,{Component} from 'react';
import ReactDOM from 'react-dom';
class App extends Component{
constructor(){
super();
this.state = {
like:true,
}
}
render(){
const list = [
{
brand: "奔驰",
list: ['c', 'e', 'g']
},
{
brand: "宝马",
list: ['x', 'z']
},
];
return (
<div><ul>
{
list.map((item,index)=><li key={index}>
车的类型:{item.brand}
{item.list.map((i, index1) => <span key={index1}>{i}</span>)}
</li>
)
}
</ul></div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
1.3、dangerouslySetInnerHTML
- 对于富文本创建的内容,后台拿到的数据是这样的
content = "<p>React.js是一个构建UI的库</p>"
- 处于安全的原因,React当中所有表达式的内容会被转义,如果直接输入,标签会被当成文本。
- 这时候就需要使用
dangerouslySetHTML
属性,它允许我们动态设置innerHTML
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor() {
super()
this.state = {
content : "<p>React.js是一个构建UI的库</p>"
}
}
render () {
return (
<div
// 注意这里是两个下下划线 __html
dangerouslySetInnerHTML={{__html: this.state.content}}
/>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
二、组件模块
组件允许我们将UI拆分为独立可复用的代码片段,并对每个片段就行独立构思。
从概念上类似于 JavaScript 函数,他接受任意传入的参数(props),并返回用于描述页面展示内容的React元素(JSX)
- 相关约定
组件的后缀可以是 .js 也可以是 .jsx,为了方便区分组件与项目的业务代码:
建议组件用 .jsx,业务代码后缀用 .js。
- 在react 中,组件的形式有2种:
- 类组件(面向对象)
1. 有状态(又称之为有状态组件)
2. 有生命周期
3. 其实就是一个构造器,每次使用组件都相当于在实例化组件
- 函数组件(面向过程)
1. 无状态(又称之为无状态组件)
2. 无生命周期
3. 直接调用
- 受控组件与非受控组件
React组件的数据渲染是否被调用者传递的
props
完全控制,控制则为受控组件,否则非受控组件。
2.1、创建类组件
在 react17 之后,允许在项目不用 “import React from “react”; ”,但是在之前的版本是不行的。建议写,肯定不会错。
- 注意点:
1. 使用ES6语法的class创建组件
2. class的名字必须首字母大写
3. class需要继承Component类(来自React)
4. class组件必须要有 redner() 方法, 用于页面结构渲染, redner() 方法必须使用return返回值,返回值要符合JSX语法
5. class最终需要被导出(export default)
- 第一种写法:
import React from "react";
// 创建class类,继承React.Component,在里面提供render方法,在return里面返回内容
class App extends React.Component {
render() {
return <div>这是一个类组件</div>;
}
}
export default App;
- 第二种写法:
// 引入react和Component
import React,{Component} from "react";
// 类组件
class App extends Component {
render() {
return <div>这是一个类组件</div>;
}
}
// 导出
export default App;
- 在16以前的版本还支持这样创建组件, 但现在的项目基本上不用
React.createClass({
render () {
return (
<div>{this.props.xxx}</div>
)
}
})
2.2、创建函数组件
- 注意点:
1. 函数组件的主体是一个函数,支持function形式和箭头函数等
2. 函数名称必须首字母大写
3. 函数组件必须使用return返回值,返回值要符号JSX语法
4. 函数组件必须要导出函数元素(export default)
import React from "react"
// 函数名首字母必须大写
const FunCmp = () => {
return <div>这是一个函数组件</div>;
};
// 导出
export default FunCmp;
2.3、组件的组合(Fragment)
- 将一个组件渲染到某一个节点里的时候,会将这个节点里原有内容覆盖
- 组件嵌套的方式就是将子组件写入到父组件的模板中去,且react没有Vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系
// 从 react 的包当中引入了 React 和 React.js 的组件父类 Component
import React,{Component} from 'react'
import ReactDOM from 'react-dom'
// 定义子组件
class Title extends Component{
render(){
return (
<h1>欢迎进入React的世界</h1>
)
}
}
class Content extends Component{
render(){
return (
<p>React.js是一个构建UI的库</p>
)
}
}
// 定义父组件,在父组件里面调用子组件
class App extends Component{
render (){
return ( //注意:根节点一定是一个标签
<div>
<Title /> <Content />
</div>
)
}
}
/*
由于每个React组件只能有一个根节点,所以要渲染多个组件的时候,需要在最外层包一个容器,如果使用div, 会生成多余的一层dom
*/
ReactDOM.render(
<App/>,
document.getElementById('root')
)
- 如果不想生成多余的一层dom可以使用
React
提供的Fragment
组件在最外层进行包裹
// 从 react 的包当中引入了 React 和 React.js 的组件父类 Component
// 还引入了一个React.js里的一种特殊的组件 Fragment
import React,{Component, Fragment} from 'react'
import ReactDOM from 'react-dom'
// 定义子组件
class Title extends Component{
render(){
return (
<h1>欢迎进入React的世界</h1>
)
}
}
class Content extends Component{
render(){
return (
<p>React.js是一个构建UI的库</p>
)
}
}
// 定义父组件,在父组件里面调用子组件
class App extends Component{
render (){
return (//注意:根节点一定是一个标签
<Fragment>{/*在根节点不想生成多一级的标签 使用 Fragment*/}
<Title /> <Content />
</Fragment>
)
}
}
/*
Fragment 简写方式 <></>
上面代码可以简写成:<> <Title /> <Content /> </>
*/
ReactDOM.render(
<App/>,
document.getElementById('root')
)
2.4、组件的嵌套
//1.引入 react
import React,{Component} from "react"
//2.引入 react-dom
import ReactDOM from 'react-dom'
//子组件
class List extends Component{
render(){
return (
<div>
<h1>欢迎进入列表</h1>
<Item></Item>
</div>
)
}
}
//孙子组件
class Item extends Component{
render() {
return <div>我们列表中的内容</div>
}
}
//父组件
class App extends Component{
render() {
return <><List /></>
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
三、组件中DOM样式
- 给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现
- 行内样式需要写入一个样式对象,而中国样式对象的位置可以放在很多地方,例如 Render 函数里、组件原型上、外链 js 文件中
// 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
<p style={{color:'red', fontSize:'14px'}}>Hello world</p>
- 我们大多数情况下还是使用类名,为元素添加样式。
- 但是需要注意的是:
class
需要写成className
,因为在 js 中class
是关键字
<p className="hello" style = {this.style}>Hello world</p>
实例
index.css
文件
.title{
width: 100%;
height:100px;
background: lightblue;
color:yellow;
}
index.js
文件
//1.引入 react
import React, { Component } from "react";
//2.引入 react-dom
import ReactDOM from "react-dom";
//引入样式
import "./index.css";
//引入图片,图片必须放在 src 的目录下
import logo from "./img/logo192.png";
//父组件
//jsx 语法中 不能直接写 class ,必须写成 className
class App extends Component {
render() {
return <div id="appRoot" style={{ color: "green" }}>
<h1 className="title">欢迎</h1>
<p>react</p>
<img src={logo} alt="logo" />
</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)