一、helloworld(可直接用浏览器打开文件即可)

cdn:bootcdn有各种js 的cdn; 一般提供开发版(js未压缩)和生产版(js压缩过了)

需要引入3个js

核心库:<script src="./node_modules/react/umd/react.development.js"></script>

操作dom的扩展库:<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>

解析jsx语法代码转为js语法代码的库:<script src="./dist/bundle.js"></script>

helloworld代码:

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8
9
10 <!-- Load React. -->
11 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
12 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
13 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
14 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
15 <div id="example"></div>
16 <script type="text/babel">
17 //1.创建虚拟DOM元素对象
18 var vDOM=<h1> HELLO WORLD</h1>
19
20 //2.将虚拟DOM渲染到真是的ROM容器中
21 ReactDOM.render(vDOM,document.getElementById("example"));
22 </script>
23
24
25 </body>
26 </html>

View Code

页面显示 HELLO WORLD

两种方式,实现react hello world;

jsx写法:const vDom2 = <h3 id={id.toLocaleUpperCase()}>{msg.toLocaleLowerCase()}</h3>;

  • "<"代表标签开始
  • “{”代表js代码开始
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8
9 <h2>Add React in One Minute</h2>
10
11 <div id="test"></div>
12 <div id="test2"></div>
13 <!-- Load React. -->
14 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
15 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
16 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
17 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
18
19
20 <script>
21 const msg = "AAAA BBBB VVV DD!";
22 const id = "xsdfsdf"
23 //1.创建虚拟DOM ;参数:标签名,标签属性(键值对);标签内容
24 const vDom1 = React.createElement("h2",{id:id.toLowerCase()},msg.toUpperCase());
25 //2.渲染虚拟DOM 参数:虚拟对象 ,DOM容器
26 ReactDOM.render(vDom1,document.getElementById("test"));
27 </script>
28
29 <script type="text/babel">
30 //1.创建虚拟DOM
31 const vDom2 = <h3 id={id.toLocaleUpperCase()}>{msg.toLocaleLowerCase()}</h3>;
32 //2.渲染虚拟DOM 参数:虚拟对象 ,DOM容器
33 ReactDOM.render(vDom2,document.getElementById("test2"));
34 </script>
35 </body>
36 </html>

 

 数组用列表形式显示:

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8 <div id="example"></div>
9 <!-- Load React. -->
10 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
11 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
12 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
13 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
14
15
16
17 <script type="text/babel">
18 //需求:数组用列表显示
19 //问题:如何将一个数据的数字转换为一个标签的数组
20 //利用数组的map函数
21 const names=["jqyer","react","vue"];
22 //1.创建虚拟DOM
23 const vDom2 = <ul>{
24 names.map((name,index)=><li key={index}>{name}</li>)
25 }</ul>
26 //2.渲染虚拟DOM 参数:虚拟对象 ,DOM容器
27 ReactDOM.render(vDom2,document.getElementById("example"));
28 </script>
29 </body>
30 </html>

View Code

 

组件编程的基本定义和使用:

简单组件(组件无状态)和复杂组件(组件有状态)

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8 <div id="example"></div>
9 <div id="example2"></div>
10 <!-- Load React. -->
11 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
12 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
13 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
14 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
15
16
17
18 <script type="text/babel">
19
20 //1.定义组件 组件名称大写
21 //方式1:工厂函数组件(简单组件) 必须要return;
22 function MyComponent(){
23 return <h2>工厂函数组件(简单组件)</h2>
24 }
25 //方式2:ES6类组件(复杂组件)
26 class MyComponent2 extends React.Component{
27 render(){
28 return <h2>ES6类组件(复杂组件)</h2>
29 }
30 }
31 //2.渲染组件,容器DOM
32 ReactDOM.render(<MyComponent/>,document.getElementById('example'));
33 ReactDOM.render(<MyComponent2/>,document.getElementById('example2'));
34 </script>
35 </body>
36 </html>

View Code

 

简单组件实现结合props的相关说明 

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8 <div id="like"></div>
9 <div id="like2"></div>
10 <!-- Load React. -->
11 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
12 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
13 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
14 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
15 <script src="/my-app/node_modules/prop-types/prop-types.min.js"></script>
16
17
18
19 <script type="text/babel">
20
21 //1.定义组件 组件名称大写
22 //方式1:
23 function PersonInfo(props){
24 return <ul><li>姓名:{props.name}</li><li>年龄:{props.age}</li><li>性别:{props.sex}</li></ul>
25 }
26
27 //指定属性默认值
28 PersonInfo.defaultProps={
29 sex:"男",
30 age:18
31 }
32 //对props中的属性今昔类型限制和必要性限制
33 // PersonInfo.propTypes = {
34 // name: PropTypes.string
35 // }
36 //2.渲染组件标签,容器DOM
37 const p1={
38 name:"TOM",
39 age:12,
40 sex:"女"
41 }
42
43 const p2={
44 name:"TOM"
45 }
46
47 //传值也可使用...p1
48 //...的作用:1.打包,2.解包
49 //1.打包 function fn(...as){} fn(1,2,3) 参数放到数组as中
50 //2.解包 const arr1=[1,2,3] const arr2=[6,...arr1,9] 即[6,1,2,3,9]
51
52 // ReactDOM.render(<PersonInfo name={p1.name} age={p1.age} sex={p1.sex}/>,document.getElementById('like'));
53 ReactDOM.render(<PersonInfo{...p1}/>,document.getElementById('like'));
54 ReactDOM.render(<PersonInfo name={p2.name}/>,document.getElementById('like2'));
55
56 </script>
57 </body>
58 </html>

View Code

 

复杂组件的相关说明:state的状态和将新增的方法强制绑定为组件对象;

state:初始化状态,读取状态,更新状态;

注意:

  • return 只能有一个根标签;
  • 将新增方法中的this强制绑定为组件对象,需要在构造器中加入t额外加入his.handleClick = this.handleClick.bind(this);如果不想在构造器中加入绑定,那么方法可以直接用箭头函数;否则一定要在构造器中绑定对象;
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8 <div id="like"></div>
9 <!-- Load React. -->
10 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
11 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
12 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
13 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
14
15
16
17 <script type="text/babel">
18
19 //1.定义组件 组件名称大写
20 //方式2:ES6类组件(复杂组件)
21 class Like extends React.Component{
22 constructor(prop){
23 super(prop)
24 //初始化状态
25 this.state={
26 isOpen:false
27 }
28 //将新增方法中的this强制绑定为组件对象
29 this.handleClick = this.handleClick.bind(this)
30 }
31 //新添加方法:内部的this默认是undefined 不是组件对象
32 handleClick(){
33 const isOpen = !this.state.isOpen
34 //更新状态
35 //this.setState({isOpen:isOpen}) 等同于this.setState({isOpen}) !
36 this.setState({isOpen})
37 }
38 //重写组件方法
39 render(){
40 console.log(this);//组件实例对象
41 //读取状态
42 const {isOpen} = this.state
43 return <h2 onClick={this.handleClick}>{isOpen?"关":"开"}</h2>
44 }
45 }
46 //2.渲染组件标签,容器DOM
47 ReactDOM.render(<Like/>,document.getElementById('like'));
48 </script>
49 </body>
50 </html>

View Code

 

ref、事件event获取元素的值 

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Add React in One Minute</title>
6 </head>
7 <body>
8 <div id="example"></div>
9 <!-- Load React. -->
10 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
11 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
12 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
13 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
14 <script src="/my-app/node_modules/prop-types/prop-types.min.js"></script>
15
16
17
18 <script type="text/babel">
19
20 //1.定义组件 组件名称大写
21 class LearnRef extends React.Component{
22 constructor(props){
23 super(props);
24 this.showInput = this.showInput.bind(this);
25 this.handleBlur = this.handleBlur.bind(this);
26 }
27 showInput(){
28 alert("方式二:"+this.elementKey.value);
29 }
30 handleBlur(event){
31 alert(event.target.value);
32 }
33 // ref={input=>this.elementKey=input} input表示当前input元素 elementKey 表示对象的键值对的键值
34 render(){
35 return <div>
36 <input type="text" ref={input=>this.elementKey=input}/><br/>
37 <input type="text" placeholder="失去焦点提示内容" onBlur={this.handleBlur}/><br/>
38 <button onClick={this.showInput}>输入提示</button>
39 </div>
40 }
41 }
42 //2.渲染组件
43 ReactDOM.render(<LearnRef/>,document.getElementById('example'));
44
45 </script>
46 </body>
47 </html>

View Code

 

组件化编程

流程:

1.拆分组件

2.实现静态组件(只有静态页面,没有动态数据和交互)

3.实现动态组件:1)。实现初始化数据动态显示;2).实现交互功能:

demo实现功能如下:

一、react基本应用_构造器


1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="UTF-8" />
6 <title>Add React in One Minute</title>
7
8 </head>
9
10 <body>
11 <div id="example"></div>
12 <!-- Load React. -->
13 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
14 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
15 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
16 <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
17 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
18
19
20
21 <!-- <script src="learn.js"></script> -->
22 <script type="text/babel">
23 //1.定义组件 组件名称大写
24 class App extends React.Component {
25 constructor(props) {
26 super(props);
27 this.state={
28 todos:["eat","sleep","coding"]
29 }
30 this.addTodo = this.addTodo.bind(this);
31 }
32
33 addTodo(todo){
34 // this.state.todos.unshift(todo); 不可以这么写
35 const {todos}=this.state;
36 todos.unshift(todo);
37 //跟新状态
38 this.setState({todos});
39
40 }
41 render() {
42
43 return (
44 <div>
45 <h1>simple todo list</h1>
46 <Add count={this.state.todos.length} addTodo={this.addTodo}/>
47 <List todos={this.state.todos}/>
48 </div>
49
50 )
51 }
52 }
53
54 class Add extends React.Component {
55 constructor(props) {
56 super(props);
57 this.add=this.add.bind(this);
58 }
59 add(){
60 const todo = this.todoItem.value.trim();
61 if(!todo){
62 return;
63 }
64 this.props.addTodo(todo);
65 }
66 render(){
67 return (
68 <div>
69 <input type="text" ref={input=>this.todoItem=input}/><button onClick={this.add}>添加#{this.props.count+1}</button>
70 </div>
71 )
72 }
73 }
74 class List extends React.Component {
75 constructor(props) {
76 super(props);
77 }
78 render(){
79 return (
80 <ul>
81 {this.props.todos.map((todo,index)=><li key={index}>{todo}</li>)}
82 </ul>
83 )
84 }
85 }
86 //参数设置限制
87 List.propTypes = {
88 todos: PropTypes.array.isRequired
89 };
90 Add.propTypes = {
91 count: PropTypes.number.isRequired,
92 addTodo:PropTypes.func.isRequired
93 };
94 //2.渲染组件
95 ReactDOM.render(<App />, document.getElementById('example'));
96
97 </script>
98 </body>
99
100 </html>

View Code

 关于限制项的另外一种写法:必须要写在组件内。表示该组件类的限制

 static propTypes = {

todos: PropTypes.array.isRequired
};

1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="UTF-8" />
6 <title>Add React in One Minute</title>
7
8 </head>
9
10 <body>
11 <div id="example"></div>
12 <!-- Load React. -->
13 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
14 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
15 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
16 <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
17 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
18
19
20
21 <!-- <script src="learn.js"></script> -->
22 <script type="text/babel">
23 //1.定义组件 组件名称大写
24 class App extends React.Component {
25 constructor(props) {
26 super(props);
27 this.state={
28 todos:["eat","sleep","coding"]
29 }
30 this.addTodo = this.addTodo.bind(this);
31 }
32
33 addTodo(todo){
34 // this.state.todos.unshift(todo); 不可以这么写
35 const {todos}=this.state;
36 todos.unshift(todo);
37 //跟新状态
38 this.setState({todos});
39
40 }
41 render() {
42
43 return (
44 <div>
45 <h1>simple todo list</h1>
46 <Add count={this.state.todos.length} addTodo={this.addTodo}/>
47 <List todos={this.state.todos}/>
48 </div>
49
50 )
51 }
52 }
53
54 class Add extends React.Component {
55 constructor(props) {
56 super(props);
57 this.add=this.add.bind(this);
58 }
59 add(){
60 const todo = this.todoItem.value.trim();
61 if(!todo){
62 return;
63 }
64 this.props.addTodo(todo);
65 }
66 render(){
67 return (
68 <div>
69 <input type="text" ref={input=>this.todoItem=input}/><button onClick={this.add}>添加#{this.props.count+1}</button>
70 </div>
71 )
72 }
73 }
74 class List extends React.Component {
75 //参数设置限制的另外一种写法
76 static propTypes = {
77 todos: PropTypes.array.isRequired
78 };
79 constructor(props) {
80 super(props);
81 }
82 render(){
83 return (
84 <ul>
85 {this.props.todos.map((todo,index)=><li key={index}>{todo}</li>)}
86 </ul>
87 )
88 }
89 }
90 //参数设置限制
91 Add.propTypes = {
92 count: PropTypes.number.isRequired,
93 addTodo:PropTypes.func.isRequired
94 };
95 //2.渲染组件
96 ReactDOM.render(<App />, document.getElementById('example'));
97
98 </script>
99 </body>
100
101

View Code

 

获取表单数据:

获取组件值的方式有两种:1.受控组件方式(表单输入数据能自动收集成状态:可以理解为onChange方式) ;2.非受控组件方式(r需要时,才手动读取输入框中的值,可以理解为ef方式)

1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="UTF-8" />
6 <title>Add React in One Minute</title>
7
8 </head>
9
10 <body>
11 <div id="example"></div>
12 <!-- Load React. -->
13 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
14 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
15 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
16 <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
17 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
18
19
20
21 <!-- <script src="learn.js"></script> -->
22 <script type="text/babel">
23 //1.定义组件 组件名称大写
24 class GetFormInfo extends React.Component {
25 constructor(props) {
26 super(props);
27 this.handleChange=this.handleChange.bind(this);
28 this.handleSubmit = this.handleSubmit.bind(this);
29 this.state={
30 pwd:''
31 }
32 }
33
34 handleChange(event){
35 const pwd = event.target.value;
36 //更新状态
37 this.setState({pwd});
38 }
39 handleSubmit(){
40 const name = this.name.value;
41 const {pwd}=this.state;
42 alert("当前填写的表单信息为:用户名:"+name+",密码:"+pwd);
43 }
44 render() {
45
46 return (
47 <form onSubmit={this.handleSubmit}>
48 用户名:<input type="text" ref={input=>this.name = input}/>
49 密码:<input type="password" onChange={this.handleChange} value={this.state.pwd}/>
50 <input type="submit" value="显示表单信息"/>
51 </form>
52
53 )
54 }
55 }
56 //2.渲染组件
57 ReactDOM.render(<GetFormInfo />, document.getElementById('example'));
58
59 </script>
60 </body>
61
62 </html>

View Code

 

组件的生命周期

1. 组件的三个生命周期状态:

  • Mount:插入真实 DOM
  • Update:被重新渲染
  • Unmount:被移出真实 DOM

2. 生命周期流程:

* 第一次初始化显示: ReactDOM.render(<Xxx/>, containDom)

  • constructor()
  • componentWillMount() : 将要插入回调
  • render() : 用于插入虚拟DOM回调
  • componentDidMount() : 已经插入回调

* 每次更新state: this.setState({})

  • componentWillReceiveProps(): 接收父组件新的属性
  • componentWillUpdate() : 将要更新回调
  • render() : 更新(重新渲染)
  • componentDidUpdate() : 已经更新回调

* 删除组件: ReactDOM.unmountComponentAtNode(div): 移除组件

  • componentWillUnmount() : 组件将要被移除回调

3. 常用的方法

  • render(): 必须重写, 返回一个自定义的虚拟DOM
  • constructor(): 初始化状态, 绑定this(可以箭头函数代替)
  • componentDidMount() : 只执行一次, 已经在dom树中, 适合启动/设置一些监听!

demo 效果图:

一、react基本应用_html_02

1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="UTF-8" />
6 <title>Add React in One Minute</title>
7
8 </head>
9
10 <body>
11 <div id="example"></div>
12 <!-- Load React. -->
13 <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
14 <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
15 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
16 <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
17 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
18
19
20
21 <!-- <script src="learn.js"></script> -->
22 <script type="text/babel">
23 //1.定义组件 组件名称大写
24 class Life extends React.Component {
25 constructor(props) {
26 super(props);
27
28 this.state={
29 opcity:1
30 }
31 this.handleClick = this.handleClick.bind(this);
32 }
33
34 componentDidMount(){
35 this.intervalId =setInterval(function(){
36 let {opcity}= this.state;
37 opcity -= 0.1;
38 if(opcity<0){
39 opcity = 1;
40 }
41 this.setState({opcity})
42 }.bind(this),500)
43 }
44 componentWillUnmount(){
45 clearInterval(this.intervalId);
46 }
47 handleClick(){
48 ReactDOM.unmountComponentAtNode(document.getElementById('example'));
49 }
50 render() {
51 const {opcity}=this.state
52 return (
53 <div>
54 <h2 style={{opacity:opcity}}> react 太难了</h2>
55 <button onClick={this.handleClick}>不活了</button>
56 </div>
57
58 )
59 }
60 }
61 //2.渲染组件
62 ReactDOM.render(<Life />, document.getElementById('example'));
63
64 </script>
65 </body>
66
67

View Code

 

组件模板:

一般写组件可以在这个模板里面写:

1 import React, { Component } from 'react';
2 export default class defalutApp extends Component {
3 constructor(props) {
4 super(props);
5 this.state = {
6 }
7 }
8 render() {
9
10 return (
11 <div>
12 </div>
13
14 )
15 }
16

View Code

 

axios 请求

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>11_ajax</title>
6 </head>
7 <body>
8 <div id="example"></div>
9
10 <script type="text/javascript" src="../js/react.development.js"></script>
11 <script type="text/javascript" src="../js/react-dom.development.js"></script>
12 <script type="text/javascript" src="../js/babel.min.js"></script>
13 <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
14 <script type="text/babel">
15 /*
16 需求:
17 1. 界面效果如下
18 2. 根据指定的关键字在github上搜索匹配的最受关注的库
19 3. 显示库名, 点击链接查看库
20 4. 测试接口: https://api.github.com/search/repositories?q=r&sort=stars
21 */
22 class AxiosComponent extends React.Component{
23 state={
24 repoName:"",
25 repoUrl:""
26 }
27 componentDidMount(){
28 const url = "https://api.github.com/search/repositories?q=r&sort=stars";
29 axios.get(url).then(response=>{
30 console.log(response.data);
31 const result = response.data
32 this.setState({
33 repoName:result.items[0].name,repoUrl:result.items[0].html_url
34 })
35 })
36 }
37 render(){
38 const {repoName,repoUrl} = this.state;
39 if(!repoName){
40 return(
41 <h2>Loading...</h2>
42 )
43 }else{
44 return <h2>最受欢迎的组件是<a href={repoUrl}>{repoName}</a></h2>
45 }
46 return(
47 <div></div>
48 )
49 }
50 }
51 ReactDOM.render(<AxiosComponent/>,document.getElementById("example"))
52 </script>
53 </body>
54 </html>

View Code

 

组件之间的参数传递:

1.props传递;以上例子都是使用props传递,不再赘述

2.使用消息订阅(subscribe)-发布(publish)机制;

  • 在当前项目安装pubsub-js:npm install --save pubsub-js
  • github地址:​​https://github.com/mroderick/PubSubJS​
  • 发布消息:PubSub.publish('MY TOPIC', 'hello world!');
  • 订阅消息:var token = PubSub.subscribe('MY TOPIC', mySubscriber);

订阅消息的说明:

var token = PubSub.subscribe('MY TOPIC', mySubscriber);

var mySubscriber = function (msg, data) { console.log(msg, data); };

订阅位置:一般是在componentDidMount() 里面设置订阅;

3.redux

react-router:

说明react v5到v6:

  • Switch 重命名为 Routes
  • Route 的新特性变更 ,component/render被element替代
  • react-router-dom 6版本移除了 Redirect,用 Navigate 代替

创建:​​npx create-react-app react-app​

1.下载 npm install --save react-router-dom

2.helloword代码:

一、react基本应用_react_03

       

一、react基本应用_react_04

 

index.html:

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6 <meta name="viewport" content="width=device-width, initial-scale=1" />
7 <meta name="theme-color" content="#000000" />
8 <meta
9 name="description"
10 content="Web site created using create-react-app"
11 />
12 <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13 <link rel="stylesheet" href="css/bootstrap.css" />
14 <title>React App</title>
15 </head>
16 <body>
17 <noscript>You need to enable JavaScript to run this app.</noscript>
18 <div id="root"></div>
19 </body>
20 </html>

View Code

app.jsx:

1 import React, { Component } from 'react';
2 import {Route, Switch, Redirect,NavLink} from 'react-router-dom'
3 import Home from '../views/home.jsx';
4 import About from '../views/about.jsx';
5 export default class App extends Component {
6 constructor(props) {
7 super(props);
8 this.state = {
9 }
10 }
11 render() {
12 return (
13 <div>
14 <div className="row">
15 <div className="col-xs-offset-2 col-xs-8">
16 <div className="page-header">
17 <h2>React Router Demo</h2>
18 </div>
19 </div>
20 </div>
21
22 <div className="row">
23 <div className="col-xs-2 col-xs-offset-2">
24 <div className="list-group">
25 {/*导航路由链接*/}
26 <NavLink className="list-group-item" activeClassName="activeClass" to='/about'>About</NavLink>
27 <NavLink className="list-group-item" activeClassName="activeClass" to='/home'>Home</NavLink>
28 </div>
29 </div>
30 <div className="col-xs-6">
31 <div className="panel">
32 <div className="panel-body">
33 {/*可切换的路由组件*/}
34 <Switch>
35 <Route path='/about' component={About}/>
36 <Route path='/home' component={Home}/>
37 {/*可切换的路由组件 默认显示about*/}
38 <Redirect to='/about'/>
39 </Switch>
40 </div>
41 </div>
42 </div>
43 </div>
44 </div>
45 )
46 }
47

View Code

home.jsx:

1 import React, { Component } from 'react';
2 export default class Home extends Component {
3 constructor(props) {
4 super(props);
5 this.state = {
6 }
7 }
8 render() {
9
10 return (
11 <div>
12 HOME
13 </div>
14
15 )
16 }
17

View Code

about.jsx:

1 import React, { Component } from 'react';
2 export default class About extends Component {
3 constructor(props) {
4 super(props);
5 this.state = {
6 }
7 }
8 render() {
9
10 return (
11 <div>
12 ABOUT
13 </div>
14
15 )
16 }
17

View Code

index.css:

1 .activeClass {
2 color: red !important;
3

View Code

index.js:

1 import React from 'react';
2 import ReactDOM from 'react-dom/client';
3 import APP from './component/app.jsx';
4 import { BrowserRouter, HashRouter } from 'react-router-dom';
5 import './index.css'
6 const root = ReactDOM.createRoot(document.getElementById('root'));
7 root.render(
8
9 //需要用路由包裹整个应用 ,意思就是路由管理整个应用
10 <BrowserRouter>
11 <React.StrictMode>
12 <APP />
13 </React.StrictMode>
14 </BrowserRouter>
15 );
16
17 // If you want to start measuring performance in your app, pass a function
18 // to log results (for example: reportWebVitals(console.log))
19 // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

View Code

包装组件:

1 import React, { Component } from 'react';
2 import {NavLink} from 'react-router-dom';
3 export default function MyNavLink(props) {
4 return <NavLink {...props} activeClassName="activeClass"/>
5

包装组件的使用:

1 import React, { Component } from 'react';
2 import {Route, Switch, Redirect,NavLink} from 'react-router-dom'
3 import Home from '../views/home.jsx';
4 import About from '../views/about.jsx';
5 import MyNavLink from './myNavLink.jsx';
6 export default class App extends Component {
7 constructor(props) {
8 super(props);
9 this.state = {
10 }
11 }
12 render() {
13 return (
14 <div>
15 <div className="row">
16 <div className="col-xs-offset-2 col-xs-8">
17 <div className="page-header">
18 <h2>React Router Demo</h2>
19 </div>
20 </div>
21 </div>
22
23 <div className="row">
24 <div className="col-xs-2 col-xs-offset-2">
25 <div className="list-group">
26 {/*导航路由链接*/}
27 <MyNavLink className="list-group-item" to='/about'>About</MyNavLink>
28 <MyNavLink className="list-group-item" to='/home'>Home</MyNavLink>
29 </div>
30 </div>
31 <div className="col-xs-6">
32 <div className="panel">
33 <div className="panel-body">
34 {/*可切换的路由组件*/}
35 <Switch>
36 <Route path='/about' component={About}/>
37 <Route path='/home' component={Home}/>
38 {/*可切换的路由组件 默认显示about*/}
39 <Redirect to='/about'/>
40 </Switch>
41 </div>
42 </div>
43 </div>
44 </div>
45 </div>
46 )
47 }
48

View Code

 

 嵌套路由:

/home   那么/home/news 就是嵌套路由;

demo修改:

效果:

一、react基本应用_react_05

 

步骤一:在views中添加路由组件news 和message

news:

1 import React, { Component } from 'react';
2 export default class News extends Component {
3 constructor(props) {
4 super(props);
5 this.state = {
6 newsArray:[
7 "news001",
8 "news002",
9 "news003"
10 ]
11 }
12 }
13 render() {
14
15 return (
16 <ul>{this.state.newsArray.map((item,index)=><li key={index}>{item}</li>)}</ul>
17 )
18 }
19

View Code

message:

1 import React, { Component } from 'react';
2 export default class Message extends Component {
3 constructor(props) {
4 super(props);
5 this.state = {
6 msgArray:[
7 ]
8 }
9 }
10 componentDidMount(){
11 //模拟发送ajax请求异步获取数据
12 setTimeout(()=>{
13 const msgArray = [
14 {"id":1,"title":"msgArray001"},
15 {"id":2,"title":"msgArray0012"},
16 {"id":3,"title":"msgArray0013"}
17 ]
18 this.setState({msgArray})
19 },1000)
20 }
21 render() {
22
23 return (
24 <ul>{this.state.msgArray.map((item,index)=>(<li key={index}><a href='???'>{item.title}</a></li>))}</ul>
25 )
26 }
27

View Code

 步骤二:修改home.jsx:

1 import React, { Component } from 'react';
2 import MyNavLink from '../component/myNavLink';
3 import {Route, Switch,Redirect} from 'react-router-dom';
4 import News from './news.jsx';
5 import Message from './message.jsx';
6 export default class Home extends Component {
7 constructor(props) {
8 super(props);
9 this.state = {
10 }
11 }
12 render() {
13
14 return (
15 <div>
16 <h2>HOME ROUTE COMPONET </h2>
17 <div>
18 <ul className='nav nav-tabs'>
19 <li>
20 <MyNavLink to="/home/news">news</MyNavLink>
21 </li>
22 <li>
23 <MyNavLink to="/home/message">message</MyNavLink>
24 </li>
25 </ul>
26 <div>
27 <Switch>
28 <Route path="/home/news" component={News}/>
29 <Route path="/home/message" component={Message}/>
30 <Redirect to='/home/news'/>
31 </Switch>
32 </div>
33 </div>
34 </div>
35
36 )
37 }
38

View Code

 

传参:

效果图:

一、react基本应用_html_06

 

 

添加一个message-detail:

1 import React from 'react'
2
3 const messageDetails = [
4 {id: 1, title: 'Message001', content: '我爱你, 中国'},
5 {id: 3, title: 'Message003', content: '我爱你, 老婆'},
6 {id: 6, title: 'Message006', content: '我爱你, 孩子'},
7 ]
8
9 export default function MessageDetail(props) {
10
11 const id = props.match.params.id
12 const md = messageDetails.find(md => md.id===id*1)
13 return (
14 <ul>
15 <li>ID:{id}</li>
16 <li>TITLE: 3333</li>
17 <li>CONTENT: 444</li>
18 </ul>
19 )
20

View Code

message.jsx,添加点击功能,动态显示详情

1 import React from 'react'
2 import {Link, Route} from 'react-router-dom'
3 import MessageDetail from "./message-detail"
4
5 export default class Message extends React.Component {
6 state = {
7 messages: []
8 }
9
10 componentDidMount () {
11 // 模拟发送ajax请求
12 setTimeout(() => {
13 const data = [
14 {id: 1, title: 'Message001'},
15 {id: 3, title: 'Message003'},
16 {id: 6, title: 'Message006'},
17 ]
18 this.setState({
19 messages: data
20 })
21 }, 1000)
22 }
23
24 ShowDetail = (id) => {
25 this.props.history.push(`/home/message/${id}`)
26 }
27
28 ShowDetail2 = (id) => {
29 this.props.history.replace(`/home/message/${id}`)
30 }
31
32 back = () => {
33 this.props.history.goBack()
34 }
35
36 forward = () => {
37 this.props.history.goForward()
38 }
39
40 render () {
41 const path = this.props.match.path
42
43 return (
44 <div>
45 <ul>
46 {
47 this.state.messages.map((m, index) => {
48 return (
49 <li key={index}>
50 <Link to={`${path}/${m.id}`}>{m.title}</Link>
51    
52 <button onClick={() => this.ShowDetail(m.id)}>查看详情(push)</button> 
53 <button onClick={() => this.ShowDetail2(m.id)}>查看详情(replace)</button>
54 </li>
55 )
56 })
57 }
58 </ul>
59 <p>
60 <button onClick={this.back}>返回</button> 
61 <button onClick={this.forward}>前进</button> 
62 </p>
63 <hr/>
64 <Route path={`${path}/:id`} component={MessageDetail}></Route>
65 </div>
66 )
67 }
68

View Code

 

路由点击刷新页面 直接刷新页面 页面跳转

1  //直接刷新
2 showDetail1(id){
3 this.props.history.push("/home/message/messagedetail/"+id);
4 }
5 //直接刷新
6 showDetail2(id){
7 this.props.history.replace("/home/message/messagedetail/"+id);
8 }
9 //前进
10 goForward(){
11 this.props.history.goForward();
12 }
13 //前进
14 goback(){
15 this.props.history.goBack();
16 }
17 //页面跳转
18 reqPage(){
19 window.location='http://www.baidu.com';
20

 

 

我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。