React 框架

1、React 框架简介

1.1、介绍

CS 与 BS结合:像 ReactVue 此类框架,转移了部分服务器的功能到客户端。将CSBS 加以结合。客户端只用请求一次服务器,服务器就将所有js代码返回给客户端,所有交互类操作都不再依赖服务器。 客户端只有在需要服务器的数据时才会使用json通信一下,其他时间都在客户端利用js操作、暂存数据这样就极大减轻了服务器压力。

1.2、React 特性

  • 虚拟DOM树

React 通过对 DOM 的模拟,最大限度地减少与DOM的交互。将网页的DOM树完全复制一份虚拟的 DOM 树放到内存中。

  •  数据驱动

维护虚拟 DOM 树,当发现某些节点发生变化时,并不一定修改原来的 DOM 树(在网页中看到的每一个区域),比如某些分支可能会发生该改变时,首先会修改虚拟树中的这几个节点,而后将这几个节点与原节点对比。才会对真正发生改变的节点做出修改。

 1.3、JSX文件 

为了构建交互式用户界面,使用了 JSXJSX 的完整版本是一个JavaScript语法扩展,它极大地简化了组件的创建。它支持HTML引用并使子组件渲染更容易。它本质上是一组 React 编写快捷方式。使用带有一些规则的 createElement 可以使源代码更具可读性和直接性。首先写jsx文件,运行时会先将所编写的jsx编译为js,编译完之后,将js文件运行在浏览器。

2、配置环境

2.1、安装 Git Bash

Git bash 下载链接
Git Bash 安装教程

2.2、安装 Node.js

Nodejs 下载链接
Nodejs 安装教程

2.3、安装 create-react-app

打开 Git Bash,直接输入下面命令执行
npm i -g create-react-app

2.4、创建 React 项目,名为 React App

在目标目录(自己存放项目的目录)下右键打开 Git Bash,执行下面的命令

create-react-app react-app  # react-app可以替换为其它名称

2.5、启动项目

进入目录,目录进到 react-app 这一层,打开 Git Bash,输入下面命令

npm start  # 启动应用

3、组件(Component) 

组件类似于一个 class,将一些 html、data(数据)、事件函数组合在一起成为一个组件

3.1、定义组件

定义好组件之后,需要将组件渲染出来,index.js 就是所有 js 的入口, 并引入React与Component组件。

// box.js 文件
import React, { Component } from 'react';  		// 快捷键:imrc 

// 引入React原因:将jsx编译为js
// 通过React.createElement()

class Box extends Component {					// 快捷键:CC
    state = {  } 								//局部变量

    // component类的函数,用来返回当前组件最后的渲染html结构
    // render方法只能返回一个标签及所包含内容
    render() { 
        return (
            <h1> Hello world</h1>
        );
    }
}
 
export default Box;
// index.js 文件
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';   		// 引入bootstrap库
import Box from './components/box';        			// 引入box

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Box /> 										// Box组件,见box.js
  </React.StrictMode>
);

3.2、React Fragment 介绍与使用

  •  render()方法只能返回一个标签及所包含内容,想返回多个并列标签时需要包含在一个标签内。
  • React.Fragment 组件能够在不额外创建 DOM 元素的情况下,让render()方法中返回多个元素。Fragments 允许将子列表分组,而无需向DOM添加额外标签。

理解起来就是在我们定义组件的时候,return里最外层包裹的div往往不想渲染到页面,那么就要用到Fragment组件了。

class Box extends Component { 
state = {  } 
render() { 
    return (
        <React.Fragment>
            <h1> Hello world</h1>
            <button>left</button>
            <button>right</button>
        </React.Fragment>
    );
}
}

3.3、在 jsx 中写 js 与 html 标签

jsx 中可以在任意地方定义 html 标签,但要注意,jsx 里的 html 标签中写 js 代码时都需要加 {} 括起来,{} 中只能写表达式。

render() { 
    return (
        <React.Fragment>
            <h1>{this.toString()}</h1>  		// html 标签内写js
            <button className="btn btn-primary">left</button>
            <button>right</button>
        </React.Fragment>
    );
}

toString(){
    return `x: ${this.state.x}`;
    // 或者
    // const {x} = this.state; //ES6写法相当于const xxx = this.state.xxx
    // return `x:${x}`;
}

3.4、设置样式

jsx文件下的html 标签中设置类名以用于 css 样式时,需要将 class =" "写为 className。 由于 jsx 下 html 标签与 js 语句混合,写 class 可能会与实际js中的同名类产生冲突。

  className

return (
        <React.Fragment>
            <h1>{this.toString()}</h1>     
            <button className="btn btn-primary m-2">left</button>
            <button className="btn btn-success m-2">right</button>
        </React.Fragment>
        // m-2 为 bootstrap 中 margin=2 的简写方式
);

  style

render() { 
    return (
        <React.Fragment>
        	// style样式:第一层{}代表里面是表达式,第二层{}代表里面是对象,即样式变量的内容
            <div style={{
                width: "50px",
                height: "50px",
                backgroundColor: "pink", 
                color: "white",
                textAlign: "center",
                lineHeight: "50px",
                borderRadius: "5px",
            }}>{this.toString()}</div>     
            <button className="btn btn-primary m-2">left</button>
            <button className="btn btn-success m-2">right</button>
        </React.Fragment>
    );
}

等价于:

styles = {
    width: "50px",
    height: "50px",
    backgroundColor: "pink", 					// css中所有 - 命名均改为驼峰命名法
}

render() { 
    return (    								// 标签内 style={this.styele} 即可
        <React.Fragment>
            <div style={this.styles}>{this.toString()}</div>     
            <button className="btn btn-primary m-2">left</button>
            <button className="btn btn-success m-2">right</button>
        </React.Fragment>
    );
}

3.5、数据驱动改变 style

将 style 与 state(局部变量) 值相关联,通过改变 state 里的值来改变 style。当局部变量改变时,通过接口实现所有被这个值影响的组件都改变。

state = { 
    x: 1,
 } 
 
getStyles() {
    let styles = {
        width: "50px",
        height: "50px",
        backgroundColor: "pink", 
        color: "white",
        textAlign: "center",
        lineHeight: "50px",
        borderRadius: "5px",
        margin: '5px',
    };

    if (this.state.x === 0){
        styles.backgroundColor = 'orange'; // 数据驱动改变style
    }
    return styles;
}
 render() { 
    return (
        // 直接调用 getStyles()函数
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div>     
            <button className="btn btn-primary m-2">left</button>
            <button className="btn btn-success m-2">right</button>
        </React.Fragment>
    );
}

3.6、渲染列表

使用 map 函数

遍历类写法需给每个标签元素定义唯一 key 属性,用来帮助React快速找到被修改的DOM元素

class Box extends Component { 
    state = { 
        x: 1,
        colors: ['red','green','blue'],   		// 定义渲染列表,这里用来修改div元素内容
     } 

    render() { 
	        return (
	            <React.Fragment>
	                {this.state.colors.map(color => (
	                    <div key={color}>{color}</div> // 这里建立div并将内容赋值为上述列表
	                ))}             
	            </React.Fragment>
   	        );
    }
	}

3.7、Conditional Rendering

A && B && C ...:从前往后,返回第一个为 false 的表达式。( 如果全为 true,就返回最后一个 true 表达式)
A || B || C ...:从前往后,返回第一个为 true 的表达式。(如果全为 false,就返回最后一个 false 表达式。)

即利用逻辑表达式的短路原则:

 render() {       
    return (     
     	<React.Fragment>   
            {this.state.colors.length === 0 && <p> No colors</p>}   
            // 即当 colors 有元素时无操作, 即当 colors 无元素时显示 No color
            {this.state.colors.map(color => (
                <div key={color}>{color}</div>
            ))}             
        </React.Fragment>           
    );
}

3.8、绑定事件

class Box extends Component {

    handleClickLeft(){
        console.log("click left",this); 
    }

    handleClickRight(){
        console.log("click right",this);
    }
    
    render() { 
        //仅仅是绑定函数,而不是在渲染时就将返回值传过来,因此handleClickleft不加()    
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
                <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
            </React.Fragment>
    }
}

此时,输出的 this 不是 Box 类,而是 undifind。

如何使得方法里的 this 仍属于 Box 类:
// 法一:箭头函数(推荐)
// 法二: bind 函数
handleClickLeft=()=>{						 // 法一:箭头函数
    console.log("click left",this); 
}

handleClickRight(){
    console.log("click right",this);
}

render() { 
     return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
            <button onClick={this.handleClickRight.bind(this)} className="btn btn-success m-2">right</button>          
        </React.Fragment>					// 法二:bind函数
    );
}

3.9、修改 state 里的值

直接 this.state.x-- 不会影响到页面div的显示的x值,
如果想要让 state 里的 x 的修改影响到render函数的话, 必须用 setState() 函数 (通过重新调用 render 修改 div 里 x 值)
class Box extends Component {
    state = { 
        x: 1,
    } 
    
    handleClickLeft = () => { 
           this.setState({				// setState() 函数
            x: this.state.x - 1
        });
    }

    handleClickRight = () => {
        this.setState({					// setState() 函数
            x: this.state.x + 1
        });
    }
    
    render() {    
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
                <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
            </React.Fragment>
        );
    }
}

3.10、通过按钮修改css属性

将 state 里的值赋值给某一样式的属性,通过按钮修改state 值从而修改 css 样式

class Box extends Component {
    state = { 
        x: 10, 							// state值
    } 

    handleClickLeft = () => { 
    this.setState({
        x: this.state.x - 10			// setState() 修改 state值, 重新调用 render() 函数
    });
	}

    handleClickRight = () => {
        this.setState({
            x: this.state.x + 10		// setState() 修改 state值,重新调用 render() 函数
        });
    }
    
    render() { 
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
                <button onClick={this.handleClickRight} className="btn btn-success m-2">right</button>          
            </React.Fragment>
        );
    }

    getStyles() {
        let styles = {
            width: "50px",
            height: "50px",
            backgroundColor: "pink", 
            color: "white",
            textAlign: "center",
            lineHeight: "50px",
            borderRadius: "5px",
            margin: '5px',
            marginLeft: this.state.x,              //  state值赋值给 css 属性值
        };

        if (this.state.x === 0){
            styles.backgroundColor = 'orange';
        }
        return styles;
    }		
}

3.11、给事件函数添加参数

handleClickRight = (step) => {
    this.setState({
        x: this.state.x + step
    });
}
handleClickRightTmp = () => {
    return this.handleClickRight(50);
}
 render() { 
    return (
        <React.Fragment>
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={this.handleClickLeft} className="btn btn-primary m-2">left</button>
            <button onClick={this.handleClickRightTmp} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}

将 handleClickRight() 函数写为箭头匿名函数后等价于: 

render() { 
    	//    绑定了一个调用含参 函数 handleClickLeft =(step)=>{ }  的匿名函数  
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
                <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
            </React.Fragment>
        );
    }

综上,Box组件的构建步骤:

1、定义 state 变量,并使得数据驱动 style

2、构造 handleClickLeft =(step)=>{ } 带参函数,利用 setState() 函数改变 state 值;调用setState()能够重新加载 render 函数,才可以对里面的 div 显示进行修改

3、给按钮的单击事件onClick绑定所写函数。这里绑定了一个调用含参函数 handleClickLeft =(step)=>{ } 的匿名函数,()=>this.handleClickRight(10)

class Box extends Component {
	
	// 1. 定义 state,并使得数据驱动style
    state = { 
        x: 10,
    } 
	
	// 2. 通过 handleClickLeft =(step)=>{ } 带参函数 与 setState()  改变state值
	//    并能够重新加载 render 函数来对里面的 div 显示进行操作
    handleClickLeft = (step) => { 
        this.setState({
            x: this.state.x - step
        });
    }

    handleClickRight = (step) => {
        this.setState({
            x: this.state.x + step
        });
    }
    
    render() { 
    	// 3. 给事件绑定函数:通过 render 函数里,按钮事件绑定函数。
    	//    绑定了一个调用含参函数 handleClickLeft =(step)=>{ }  的匿名函数  
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
                <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
            </React.Fragment>
        );
    }

    getStyles() {
        let styles = {
            width: "50px",
            height: "50px",
            backgroundColor: "pink", 
            color: "white",
            textAlign: "center",
            lineHeight: "50px",
            borderRadius: "5px",
            margin: '5px',
            marginLeft: this.state.x,	// 数据驱动 style
        };

        if (this.state.x === 0){
            styles.backgroundColor = 'orange';
        }
        return styles;
    }
}

4、Component 组件的组合与交互

4.1、【组合 Component 】组件的构建

组合多个上述定义的 Box 组件,形成 Boxes 组件,并完成 属性 值的传递。
<注:多个相同子组件时,每个子组件需要有唯一 key 值>
  • 建立 Boxes 类组件,内含多个 Box组件
import React, { Component } from 'react';
import Box from './box';

class Boxes extends Component {
	// 1. 设置 state 变量,包括 Box 组件的唯一 key 值与 x 坐标值。
    state = {  
        boxes:[
            {id: 1, x: 10},
            {id: 2, x: 10},
            {id: 3, x: 100},
            {id: 4, x: 10},
            {id: 5, x: 10},
        ]
    } 
    // 2. render 函数返回多个 box 组件,通过 map 列表,逐一建立并赋值多个 Box 组件
   	//    将 box.id 赋值给组件唯一 key,将 box.x 赋值给 Box 组件的 x
    render() { 
        return (
            <React.Fragment>
               {this.state.boxes.map((box)=>(
                    <Box
                        key = {box.id} // id
                        x = {box.x}    // 这里会自动找到 Box 组件里的 x 赋值并存储在 props 中
                        			   // 但仅仅是修改了x,并不会改变前端的显示
                    />
               ))}
            </React.Fragment>
        );
    }
}

export default Boxes;

【注】在react组件之间的通信是通过props属性来完成的,比如父组件需要将数据传递给子组件,那么组件在渲染子组件的时候,直接将数据作为子组件的属性传参。

  •  state 值传递:通过 props 将 Boxes定义的属性值返回传递给 Box
class Box extends Component {
    state = { 
        // props类似于state,存储除key以外属于 box 的所有属性
        // Boxes 建立的 Box 赋值的 x 存到了 props 里
        // 通过 props 传递给了每个 Box
        x: this.props.x,
    } 

    handleClickLeft = (step) => { 
        this.setState({
            x: this.state.x - step
        });
    }

    handleClickRight = (step) => {
        this.setState({
            x: this.state.x + step
        });
    }
    
    render() { 
        return (
            <React.Fragment>
                <div style={this.getStyles()}>{this.toString()}</div> 
                <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
                <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
            </React.Fragment>
        );
    }

    getStyles() {
        let styles = {
            width: "50px",
            height: "50px",
            backgroundColor: "pink", 
            color: "white",
            textAlign: "center",
            lineHeight: "50px",
            borderRadius: "5px",
            margin: '5px',
            marginLeft: this.state.x,
        };

        if (this.state.x === 0){
            styles.backgroundColor = 'orange';
        }
        return styles;
    }

    toString(){
        return `x: ${this.state.x}`;	        
    }
}
 
export default Box;
  • 标签传递:通过 props 将Boxes 增加的Box.children子标签,传递给 Box
 // Boxes.jsx文件
 render() { 
    return (
        <React.Fragment>
           {this.state.boxes.map((box)=>(
                <Box key = {box.id} x = {box.x}> 
                    <p>Box :</p>				// 将 Box 的闭合标签写为双标签
                    <div>{box.id}</div>			// 可在 Box 标签内增加其它标签,属性名为 Box.children
                </Box>							// 并存储到了 props 中																
           ))}
        </React.Fragment>
    );
}
// Box.jsx 文件
render() { 
    console.log(this.props); 
    return (
        <React.Fragment>
            {this.props.children[0]}			// 通过 props 所存储的 children 将增加的标签传递给Box
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
            <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>          
        </React.Fragment>
    );
}
  • 方法传递1:React 子组件调用父组件的方法。

Box子组件调用Boxes父组件内的方法,依旧通过props。实现在 Box 组件中触发 onClick 事件后,在Boxes组件中删除key值对应的Box,即在Box标签内调用Boxes标签的方法

 // Boxes.jsx 文件
 // 1. Boxes.jsx 文件中写删除的方法
 handleDelete = (id) => {
    // filter: boxes列表的元素依次判断,若表达式为true则留下,否则删掉
    // 即若id不等留下来,相等删除
    const newboxes = this.state.boxes.filter(
        (x)=>(x.id !== id)
    );
    this.setState({
        boxes: newboxes
    })
 }

 render() { 
    if(this.state.boxes.length === 0){
        return <div className='alert alert-dark'>没有元素可以删除了!!!</div>
    }
    return (
    	// 2. 将所写删除方法定义为标签的 onDelete 属性传递给 Box(会存储在 props中)
        <React.Fragment>
           {this.state.boxes.map((box)=>(
                <Box key = {box.id} id={box.id} x = {box.x} onDelete = {this.handleDelete}> 
                    <p>Box :</p>
                    <div>{box.id}</div>   
                </Box>
           ))}
        </React.Fragment>
    );
}
// Box.jsx 文件
 render() {    
    return (
        <React.Fragment>
            {this.props.children[0]}
            <div style={this.getStyles()}>{this.toString()}</div> 
            <button onClick={()=>this.handleClickLeft(10)} className="btn btn-primary m-2">left</button>
            <button onClick={()=>this.handleClickRight(10)} className="btn btn-success m-2">right</button>
            // 3. Box 调用 Boxes 的删除方法 :
            //    Box 中的 Button 的 onClick 事件,绑定匿名函数来调用含参的删除方法        
            <button onClick={()=>this.props.onDelete(this.props.id)} className='btn btn-danger m-2'> Delete </button>
        </React.Fragment>
    );
}
  • 方法传递2:React 父组件调用子组件的方法。

仅能调用一个子组件方法,无法调用列表子组件

// 父组件
class Boxes extends Component {

	// 1. Boxes 父组件中写入
	setChildRef = (ref) => {
        this.ChildRef = ref;
    }
    
	// 3. Boxes 父组件中写调用 Box 子组件的方法
    handleReset = () =>{
        this.ChildRef.handleRE()
    }
	
	render() {     
        return (
            <React.Fragment>
   // 4. 将父组件方法绑定onClick单击事件中,即可实现单击调用子组件的方法
                <button onClick={this.handleReset} className='btn btn-primary'> Clear </button>
               {this.state.boxes.map((box)=>( 
   // 2. Boxes 父组件的 Box 子组件标签内增加 ref 属性,并将 setChildRef 传递过来
                    <Box key = {box.id} ref={this.setChildRef} id={box.id} x = {box.x} onDelete = {this.handleDelete}> 
                        <p>Box :</p>
                        <div>{box.id}</div>   
                    </Box>
               ))}
            </React.Fragment>
        );
    }
 }
// 子组件
class Box extends Component {
    
    state = { 
        x: this.props.x,
    } 
	
	//  子组件中被调用的方法
    handleRE = () =>{
        this.setState({
            x: 0
        });
    }


    render() { 
        return (
            <React.Fragment>
                ......
            </React.Fragment>
        );
    }
}

5、组件使用

5.1、组件的生命周期

创建时(挂载阶段) 

  • 执行时机:组件创建时(页面加载时)
  • 执行顺序:constructor() -> render() -> componentDidMount()

constructor()组件创建的时候,最先执行,主要是初始化数据,为事件处理程序绑定this

render():每次组件渲染触发,主要是渲染UI

componentDidMOunt():组件挂载完成,主要作用DOM操作,发送网络请求

更新时(更新阶段)

  • 执行时机:1.setState() 2.组件收到props变了 3.forceUpdate()
  • 说明:以上3中情况都会触发
  • 执行顺序:render() -> componentDidUpdate()

render():每次组件渲染触发,渲染UI

componentDidUpdate():组件 状态更新完毕

预载时

  • 执行时机:组件从页面消失

 5.2、动态更新initialValue的值

[antd: Form.Item] defaultValue will not work on controlled Field. You should use initialValues o
原因
:antd禁止在form.item下的组件使用默认属性
解决办法:删除defaultValue,在中使用initialValue={{ parentId: parentId }}代替,如果要动态更新 parentId的值,又会导致下面的问题

React does not recognize the initialValue prop on a DOM element.
**原因:**不能通过这种方法更新parentId的值,想要更新props中的值,要通过form.setFieldsValue({ parentId: parentId })进行更改,

你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。

由上可知,表单中不能设置默认值,要想设置默认值必须通过form中的initial Values进行设置,但是其又不能动态更新,想要达到动态更新的效果必须使用form中的setFieldsValue进行更新,需要检测parentId的变化从而对parentId进行修改,固需要在useEffect中使用setFieldsValue

如果需要在父组件中得到子组件的form表单中的值,可以通过函数传参的方式,将子组件的form对象传递给父组件,这样父组件得到子组件的form对象,就可以通过getFieldValue得到表单的值了。

    const [form] = Form.useForm()
    //将子组件的form传递给父组件,使得父组件可以取到子组件form中的categorieName的值
    props.setForm(form)
    // 动态更新parentId的值
    useEffect(() => {
        form.setFieldsValue({ parentId: parentId })
    }, [parentId])
import React, { Fragment, useEffect } from 'react'
import { Form, Input, Select } from 'antd'
import { useForm } from 'antd/lib/form/Form';

const { Option } = Select;

export default function AddForm(props) {
    const { categorys, parentId } = props
    const [form] = Form.useForm()
    console.log(parentId)
    // 动态更新parentId的值
    useEffect(() => {
        form.setFieldsValue({ parentId: parentId })
    }, [parentId])
    return (
        <Fragment>
            {/* initialValues不能被动态更新,需要使用form.setFieldsValues进行动态更新,将其放在useEffect中 */}
            <Form form={form}>
                <span>所属分类</span>
                <Form.Item
                    name="parentId"
                    rules={[
                        {
                            required: true,
                            message: 'Please select category!',
                        },
                    ]}
                >
                    {/* 表单中不能使用默认属性defaultValue,在form中使用initialValues{{}}代替 */}
                    <Select >
                        <Option value='0'>一级分类</Option>
                        {
                            categorys.map(c => <Option key={c._id} value={c._id}>{c.name}</Option>)
                        }
                    </Select>
                </Form.Item>
                <span>分类名称</span>
                <Form.Item
                    name="categoryName"
                    rules={[
                        {
                            required: true,
                            message: 'Please input your categoryName!'
                        }
                    ]}
                >
                    <Input placeholder="添加分类" />
                </Form.Item>
            </Form>
        </Fragment >
    )
}

// 告警标签
// 动态更新initialValue值
changeMissLevel = () =>{
    const{form} = this.props;
    form.setFieldsValue(
        {
            missLevel:'222'
        }
    );
}

render(){
    <Form.Item>
        {getFieldDecorator('missLevel',{
                initialValue:this.state.missLevel
            })(
                  <Select
                       onChange={this.changeMissLevel}
                  >
                    <Option value= '1'>a</Option>
                    <Option value= '2'>b</Option>
                  </Select>
  
              )
        }
    </>
}

5.3、遍历、转换、非空判断、动态设置

  • 遍历对象与数组
// 遍历对象
const object  = {"a":"1","b":"2"};
for(let key in object){
    console.log(key);
    console.log(object[key]);
}

// 遍历数组
const array = ["1","2","3"];
const array1 = [{"a":"1"},{"b":"2"}];

for(let key in array){
    console.log(array[key]);
}
for(let key in array1){
    console.log(array[key].a);
    console.log(array[key].b);
}
  •   对象动态值获取或作为键 
// 动态值作为键
const obj = {"a":"1","b":"2"};
let ccc = 'c';
obj[ccc] = '3';
// 对象赋值
obj.d = '4';
// 对象获取值
let ddd = obj.d;

// 对象动态值获取
const data = {"a":"1","b":"2"};
let aaa = 'a';
data[aaa+'']
  • 对象与字符串的转换 
// 对象转字符串
const obj = {"a":"1"}
JSON.String(obj );
// 字符串转对象
String a = "";
JSON.parse(a);

// join与split
const aa = ["1","2"];
const bb = "1,2";
bb = aa.join(',');
aa = bb.split(",");
  • 非空判断 
// 判断是否不为空
ifNotNull = (value:any) => {
    if( value != undefined &&
        value != null &&
        value != 'null' &&
        value != 'NULL' &&
        value != '[]' &&
        value != '' &&
        value != {} &&
        value != [] &&
      )
    {
       return true;     
    } else {
       return false;
    }
}

// 判断是否为空
ifNotNull = (value:any) => {
    if( value === undefined ||
        value === null ||
        value === 'null' ||
        value === 'NULL' ||
        value === '[]' ||
        value === '' ||
        value === {} ||
        value === [] ||
      )
    {
       return true;     
    } else {
       return false;
    }
}

6、Hooks

6.1、

6.2、

6.3、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/103511.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

禁止拷贝文件到U盘的解决办法

禁止拷贝文件到U盘的解决办法 安企神U盘管理系统下载使用 说到这问题&#xff0c;大多情况下是企业的需求&#xff0c;很多公司电脑中都保存着极为重要的数据&#xff0c;这些数据往往是不能传播的&#xff0c;所以此时就需要禁止拷贝文件到U盘来防止公司数据被泄密。 禁止拷…

python造测试数据存到excel

代码&#xff1a; from ExcelHandler import ExcelHandler from faker import Faker # 导入faker库的Faker方法 # ↓默认为en_US&#xff0c;只有使用了相关语言才能生成相对应的随机数据 fkFaker(locale"zh_CN")def create_date():m int(input(请输入要造的数据条…

自动驾驶的商业应用和市场前景

自动驾驶技术已经成为了交通运输领域的一项重要创新。它不仅在改善交通安全性和效率方面具有巨大潜力&#xff0c;还为各种商业应用提供了新的机会。本文将探讨自动驾驶在交通运输中的潜力&#xff0c;自动驾驶汽车的制造商和技术公司&#xff0c;以及自动驾驶的商业模式和市场…

基于OpenCV批量分片高像素影像

基于OpenCV批量分片高像素影像 为了更加精确的诊断和治疗&#xff0c;医疗影像往往是大像素&#xff08;1920x1080&#xff09;或超大像素图像&#xff08;4k图像4096x2160&#xff09;。这类图像的尺寸与深度学习实验数据常见尺寸&#xff08;227x227&#xff0c;或32x32&…

OpenCV实现物体尺寸的测量

一 &#xff0c;项目分析 物体尺寸测量的思路是找一个确定尺寸的物体作为参照物&#xff0c;根据已知的计算未知物体尺寸。 如下图所示&#xff0c;绿色的板子尺寸为220*300&#xff08;单位&#xff1a;毫米&#xff09;&#xff0c;通过程序计算白色纸片的长度。 主要是通过…

我国有多少个港口?

港口是什么&#xff1f; 港口是海洋运输中不可或缺的重要设施之一&#xff0c;是连接陆路和水路运输的重要节点。港口通常是指位于沿海地区的水陆交通枢纽&#xff0c;是船舶停靠、装卸货物、储存物资和维修船只的场所。港口一般由码头、泊位、仓库、货场、客运站等设施组成&a…

数据结构和算法概述

什么是数据结构&#xff1f; 官方解释&#xff1a; 数据结构是一门研究非数值计算的程序设计问题中的操作对象&#xff0c;以及他们之间的关系和操作等相关问题的学科。 大白话&#xff1a; 数据结构就是把数据元素按照一定的关系组织起来的集合&#xff0c;用来组织和存储…

【网安大模型专题10.19】※论文5:ChatGPT+漏洞定位+补丁生成+补丁验证+APR方法+ChatRepair+不同修复场景+修复效果(韦恩图展示)

Keep the Conversation Going: Fixing 162 out of 337 bugs for $0.42 each using ChatGPT 写在最前面背景介绍自动程序修复流程Process of APR (automated program repair)1、漏洞程序2、漏洞定位模块3、补丁生成4、补丁验证 &#xff08;可以学习的PPT设计&#xff09;经典的…

Spring Cloud之服务熔断与降级(Hystrix)

目录 Hystrix 概念 作用 服务降级 简介 使用场景 接口降级 服务端服务降级 1.添加依赖 2.定义接口 3.实现接口 4.Controller类使用 5.启动类添加注释 6.浏览器访问 客户端服务降级 1.添加依赖 2.application.yml 中添加配置 3.定义接口 4.Controller类使用 …

解读意大利葡萄酒分类系统

由于该国众多的产区和复杂的品种&#xff0c;要想真正掌握意大利葡萄酒是相当困难的。仅仅是试图从复杂混乱的葡萄酒标签中辨别信息的想法就足以让许多人焦虑不安。 位于托斯卡纳的基安蒂酒地区&#xff0c;Il Ciliegio生产的葡萄酒标签上包含以下名称之一:基安蒂酒科利塞内西…

通过IP地址可以做什么

通过IP地址可以做很多事情&#xff0c;因为它是互联网通信的基础之一。本文将探讨IP地址的定义、用途以及一些可能的应用。 IP地址的用途 1. 设备标识&#xff1a;IP地址用于标识互联网上的每个设备&#xff0c;这包括计算机、服务器、路由器、智能手机等。它类似于我们日常生…

unity 一键替换 UI上所有字体,批量替换字体(包括:Text和Text (TMP))

前言&#xff1a;在开发中会遇到这种情况&#xff0c;开发完了&#xff0c;发现UI字体没有替换&#xff0c;特别是需要发布到WebGL端的同学&#xff0c;突然发现无法显示汉字了。下面一个非常方便的方法完美解决。 1.解压出来的脚本放在Edit文件下&#xff0c;没有的创建一个 2…

Linux 基于sysfs的GPIO读写操作

https://bbs.huaweicloud.com/blogs/297252 前言 最近接触到Linux系统中的GPIO开发&#xff0c;这里做个小总结&#xff0c;也分享一下&#xff1b;本文会介绍GPIO的读写&#xff0c;介绍基本原理&#xff0c;以及不同读写方式的性能。 一、GPIO sysfs interface 基本原理 …

计算机视觉中的数据预处理与模型训练技巧总结

计算机视觉主要问题有图像分类、目标检测和图像分割等。针对图像分类任务&#xff0c;提升准确率的方法路线有两条&#xff0c;一个是模型的修改&#xff0c;另一个是各种数据处理和训练的技巧(tricks)。图像分类中的各种技巧对于目标检测、图像分割等任务也有很好的作用&#…

Http长连接同一个socket多个请求和响应如何保证一一对应?

HTTP/2引入二进制数据帧和流的概念&#xff0c;其中帧对数据进行顺序标识&#xff0c;如下图所示&#xff0c;这样浏览器收到数据之后&#xff0c;就可以按照序列对数据进行合并&#xff0c;而不会出现合并后数据错乱的情况。同样是因为有了序列&#xff0c;服务器就可以并行的…

从REST到GraphQL:升级你的Apollo体验

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

【Java系列】ArrayList

ArrayList 添加元素访问元素修改元素删除元素计算大小迭代数组列表其他的引用类型ArrayList 排序Java ArrayList 方法系列文章系列文章版本记录 引言 ArrayList 类是一个可以动态修改的数组&#xff0c;与普通数组的区别就是它是没有固定大小的限制&#xff0c;我们可以添加或删…

Guava-RateLimiter详解

简介&#xff1a; 常用的限流算法有漏桶算法和令牌桶算法&#xff0c;guava的RateLimiter使用的是令牌桶算法&#xff0c;也就是以固定的频率向桶中放入令牌&#xff0c;例如一秒钟10枚令牌&#xff0c;实际业务在每次响应请求之前都从桶中获取令牌&#xff0c;只有取到令牌的请…

structs2 重构成SpringBoot架构

structs2 重构成SpringBoot架构 目录参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,challenge Survive. happy for hardess to solve den…

JAVA电商平台免费搭建 B2B2C商城系统 多用户商城系统 直播带货 新零售商城 o2o商城 电子商务 拼团商城 分销商城

涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …