React入门简单练习

陈志
2023-12-01

利用react开发一个简单的博客系统,
首先我们简单的了解一下react的简单实用
博客的功能

信息发布系统

  1. 登录管理
  2. 博客发布
  3. 后台管理
  4. 权限管理

什么是前端开发?

将页面显示和业务逻辑独立,使用组件开发,解决传统页面代码混合html显示及js业务代码的弊端

常见的框架:

  1. react(facebook,react-native)
  2. vue
  3. AngularJS

nodejs的出现使JS代码的开发脱离了浏览器并且提供了统一的构建环境及包管理工具

实验流程

基本项目结构

  1. 使用vscode打开相应文件夹(file->open)
  2. 打开terminal->new terminal 执行 npm init -y,生成package json
  3. 创建dist 及 src目录
  4. 在src目录下创建index.html和index.js

什么是SPA?(单页面应用程序)

初始化环境

  1. npm i react --save
  2. npm i react-dom --save
  3. npm i webpack -g 安装到全局作用域
  4. npm i webpack-cli -g 安装到全局作用域
  5. npm i webpack-dev-server --save-dev
  6. npm i webpack --save-dev
  7. npm i webpack-cli --save-dev
  8. 在项目根目录创建webpack.config.js(webpack的配置文件)

开始开发

  1. 在index.html添加相应代码


    第一个react程序





    </html>
    
    1. 在index.js添加相应代码:
      console.log(“ok”)

    2. 执行webpack进行打包编译

    3. 执行webpack-dev-server,启动测试服务器
      (
      如果出现webpack-dev-server无法找到使用
      npm i webpack-dev-server -g
      进行全局安装
      )
      注意事项:webpack 4.x以后,默认查找scr/index.js作为打包入口

如何在开发中热部署程序(修改后立即生效)

  1. npm i html-webpack-plugin --save-dev
  2. 在webpack.config.js中添加下述代码选择开发模式
 	module.exports = {
    mode:'development',
	}

备注:CommonJS、RequireJS是JS下的两个包管理规范

  1. 初始化html-webpack-plugin,添加如下代码到webpack.config.js最开始部分

     	 let path = require('path')
     	//创建htmlPlugin对象
     	let HtmlWebpackPlugin = require('html-webpack-plugin')
     	
     let htmlPlugin = new HtmlWebpackPlugin({
     	    template:path.join(__dirname,'./src/index.html'),//指明模版位置
     	    filename:'index.html'//访问的文件名
     	})
    

5.在module.exports中加载插件

```

 	module.exports = {
    mode:'development',
    plugins:[
        htmlPlugin
    ]
	}

```

基本的react页面生成,在index.js里添加如下代码

  	import React from 'react'
	import ReactDom from 'react-dom'

	let myli  = React.createElement('li',null,'这是一个React标题')//创建一个li元素
	let mydiv = React.createElement('div',null,myli) //创建一个div,包含li

	ReactDom.render(mydiv,document.getElementById('app'))

react在内存中生成一棵虚拟DOM树基于diff算法对DOM树的增删改查进行监控

使项目支持JSX语法

  1. 安装基本的babel依赖

    npm i babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-react babel-preset-stage-0 --save-dev

  2. 在项目根目录创建babel配置文件.babelrc,并且添加如下内容:

     {
         "presets":["env","stage-0","react"],
         "plugins":["transform-runtime"]
     }
    

3.在webpack.config.js中添加module模块,用来处理jsx的语法文件

 	 module:{
        rules:[
            {test:/\.js|jsx$/, use:'babel-loader',exclude:/node_modules/},
        ],
    }

4.在index.js里面添加一个function定义的组件,其中return中直接写html代码写法就是JSX语法,该语法会被babel-load自动解释成eact.createElement的形式。react组件可以像内置html标签一样使用例如

 	function MyList(props) {

    return  <div>
        <li>李白</li>
        <li>白居易</li>
        <li>杜甫</li>
        <li>柳宗元</li>
    </div>
}

ReactDom.render(<MyList></MyList>,document.getElementById('app'))
  1. 如何向组件传递参数
    jsx语法中如果要使用js,必须使用大括号括起来

  2. {props.libai}

  3. 使用{…对象}展开运算符进行参数传递:
    //如何传递参数
    function MyList(props) {

        return  <div>
            <li>{props.libai}</li>
            <li>{props.dufu}</li>
            <li>{props.baijuyi}</li>
        </div>
    }
    
    let poems = {libai:'李白',dufu:'杜甫',baijuyi:'柳宗元'}
    ReactDom.render(<MyList {...poems}></MyList>,document.getElementById('app'))
    

    展开运算符{…对象}相当于:

创建独立的组件

  1. 在src中创建components文件夹

  2. 在components中创建MyList.jsx

  3. 在MyList.jsx中添加如下代码:

    		import React from 'react' 
    		function MyList(props) {
    
     	    return  <div>
     	        <li>{props.libai}</li>
     	        <li>{props.dufu}</li>
     	        <li>{props.baijuyi}</li>
     	    </div>
     	 }
     	 
     	 export default MyList;
    

    4.在index.js中引入组件:

    		import MyList from './components/MyList.jsx'
     	
     	//使用方法和上例一样
    

    5.如何自动引入组件扩展名及使用’@'别名,在webpack.config.js中添加如下配置:

    		resolve:{
         extensions: ['.js', '.jsx', '.json'],
         alias: {
             '@': path.join(__dirname,'./src')
         }
     }
    

创建基于类的组件

  1. 在components下创建MyListClass.jsx文件

  2. 添加如下代码:

    	import React from 'react'
    	class MyListClass extends React.Component{ 
    
     constructor(){
         super()
     }
     render(){
        return <div>
         <li>{this.props.libai}</li>
         <li>{this.props.dufu}</li>
         <li>{this.props.baijuyi}</li>
        </div>
    
     }
    

    }

     export default MyListClass;
    
  3. 在index.js中引入类组件

    import MyListClass from '@/components/MyListClass'
    let poems = {libai:'李白',dufu:'杜甫',baijuyi:'柳宗元'}
    

    ReactDom.render(<MyListClass {…poems}>,document.getElementById(‘app’))

怎么创建评论列表

  1. 创建CmtList组件

    import React from ‘react’
    import CmtItem from ‘@/components/CmtItem’

    class CmtList extends React.Component{

     constructor(){
         super()
         //由于class组件可以设置state属性,所以是有状态组件
         //function是无状态组件
         this.state = {
             commentList:[
                 {id:1,name:'张三',title:'沙发',content:'抢沙发'},
                 {id:2,name:'李四',title:'板凳',content:'抢板凳'},
                 {id:3,name:'王五',title:'茶几',content:'抢茶几'},
             ]
         }
     }
    
     render(){
    
         return <div>
             <h2>评论内容</h2>
             <br/>
             {this.state.commentList.map(item=>
                 <div key={item.id}>
                     <CmtItem {...item}/>
                  </div>
             )}
         </div>
     }
    

    }
    export default CmtList

2.创建CmtItem组件

import React from 'react'


class CmtItem extends React.Component{

    constructor(){
        super()
    }

    render(){
        return  <div>
            <h3>{this.props.title}</h3>
            <p>内容:{this.props.content}</p>
            <p>发帖人:{this.props.name}</p> 
            </div> 
    }

}

export default CmtItem;

3.在index.js中使用CmtList组件

import CmtList from '@/components/CmtList'
ReactDom.render(<CmtList></CmtList>,document.getElementById('app'))

使用React组件访问后端restful接口

  1. 创建SearchContent.jsx组件并安装jquery

安装jquery

npm i jquery --save

创建组件

import React from 'react'
import $ from 'jquery'
import CmtItem from '@/components/CmtItem' 


class SearchContent extends React.Component{

    constructor(){
        super()
        this.state = {lists:[
            {id:1,name:'python',title:'求助',content:'python崩溃了'}
        ]}

    }

    get_data = () => {
        let t = this
        $.ajax(
            {
                url:"http://localhost:5000/api/tasks",
                dataType:"json",
                success:function(results){
                    t.setState( {
                        lists:results.Comments
                    })
                }
            }
        )   
        
    }
    render(){
         return <div>

         <h2 style={{textAlign:'center'}}>网络评论列表</h2>
         <button onClick={this.get_data}>请求网络数据</button>
         <br/>
         {this.state.lists.map(
            item=><div key={item.id}>
                <CmtItem {...item}/>
            </div>

         )}

         </div>
    }

}

export default SearchContent;

2.创建Flask服务器

from flask import jsonify,Flask
from flask_cors import cross_origin

app = Flask(__name__)
commentList = [
    {
        "id":1,
        "name":"jack",
        "title":"react",
        "content":"react真简单"
    },
    {
        "id":2,
        "name":"lily",
        "title":"python",
        "content":"python真简单"
    }

]

@app.route("/api/tasks",methods=['GET'])
@cross_origin()
def get_task():
    return jsonify({"Comments":commentList})

if __name__ == '__main__':
    app.run(debug=True)

3.使用SearchContent.jsx,在index.js中添加代码

import SearchContent from '@/components/SearchContent'
ReactDom.render(<SearchContent></SearchContent>,document.getElementById('app'))

4.关于跨域问题

  • jsonp解决跨域问题的本质
    使用引用外部js脚本不受跨域问题影响的特点设计的一种调用方法

  • 比较通用解决跨域问题的方法
    在响应头中设置Access-Control-Allow-Origin属性,例如python flask中可以按照如下实现

    ```
     @app.after_request
    

    def af_request(resp):

    resp = make_response(resp)
    resp.headers[‘Access-Control-Allow-Origin’] = ‘*’
    resp.headers[‘Access-Control-Allow-Methods’] = ‘GET,POST’
    resp.headers[‘Access-Control-Allow-Headers’] = ‘x-requested-with,content-type’
    return resp

    
    
    
    
  • Flask中的其他解决方式
    使用flask-cors库,其中cross_origin指定函数允许跨域:
    @cross_origin()
    def get_tasks():
    return jsonify({‘tasks’: tasks})

    或者使用CORS全局解决
    if name == ‘main’:
    app.run(debug=True)
    CORS(app)

  • 跨域带来的问题

    过多的跨域请求会给服务器带来安全性问题

  • 更好的解决方案

    使用nginx代理转发

React实现博客

运行方式

  1. 解压缩React-Express-Blog-Demo-master
  2. cd React-Express-Blog-Demo-master
  3. cnpm i (备注:如果系统没有cnpm执行:npm i cnpm -g 进行安装)
  4. 进入mongodb安装目录的bin目录,执行 ./mongod --dbpath ./ (./可以替换为自己的数据库路径,改步骤为启动mongodb)
  5. 进入mongodb安装目录的bin目录,执行 ./mongorestore --db blog @blogdata所在目录 注意:将 @blogdata所在目录替换为自己本机blogdata目录,该步骤为恢复数据库文件
  6. 重新进入React-Express-Blog-Demo-master,执行:npm start

关键组件

1.react-redux 在组件之间共享状态

2.react-route 组件的路由工具

3.antd 一个组件库

4.mongoose ORM工具类似于Flask-SQLAlchemy

5.cookies react处理cookies的工具

查看代码的主要流程

1.app/index.js是入口文件,Provider组件是react-redux提供状态共享的提供者

2.containers/index.js 是下一层组件,提供了主要的路由方式

3.containers/front/Front.js 是主页面

4.主页面中的组件是轮播图,是标签页组件,是详情页列表组件,是登陆组件

 类似资料: