react基础

162 阅读5分钟

创建react项目

全局安装create-react-app
cnpm install -g create-react-app
创建react项目方式一:
create-react-app reactdemo
创建react项目方式二:(版本要求node>=6  and  npm>=5.2)
npx create-react-app reactdemo
jsx是html 和js混合模式

React 创建组件、绑定属性( 绑定class  绑定style)、引入图片  循环数组渲染数据

dom渲染变量

<div>{this.state.msg}</div> 类似于vue的<div>{{this.state.msg}}</div>

标签属性用变量

title={this.state.tite}  类似于vue的 :title="state.title"

dom添加class方式一:(写死)

<div className="red" ></div>  添加一个class

dom添加class方式二:(通过变量)

<div className={this.state.color} ></div>  添加一个class

dom的的for关键字用htmlFor代替

<label htmlFor="name">姓名</label>
<input id="name" />

行内样式

<div style={{"color":"red"}}></div>

<div style={this.state.stype}></div>

引入图片

import logo from  './1.jpg'
<img   src={logo}/>
<img   src={require('./1.jpg')}/>

解析html

<div dangerouslySetInnerHTML={{_html:this.state.list.content}}></div>

渲染数组(三种方法)

class News extends React.Component{
    constructor(props){
        super(props);
        this.state = {
           list:[11111,22222,33333],
           list2:[<h2 key='1'>我是一个h2</h2>,<h2 key='2'>我是一个h2</h2>],
           list3:[
                {title:"新闻1111"},
                {title:"新闻2222"},
                {title:"新闻3333"},
                {title:"新闻4444"},
           ]
        }
    },
    render(){
        let listResult = this.state.list.map(function(value,key){
            return <li key={key}>{value}</li>
        })
        return(){
            <div className="news">
                {this.state.list2}
                <hr/>
                <ul>{listResult}</ul>
                <hr/>
                <ul>
                {
                  this.state.list3.map(function(value<key){
                      return (<li key={key}>{value.title}</li>);
                 })
                }
              </ul>
            </div>
        }
    }
}

React事件 方法、 React定义方法的几种方式 获取数据 改变数据 执行方法传值

class Home extends React.Component{
    constructor(props){
        super(props);
        this.state = {
           msg:'我是一个home组件',
           message:'我是一个message',
           username:'itying',
        }
        //  改变this指向方式一:
        this.getMessage = this.getMessage.bind(this);
    },
    run(){
        alert("我是一个run方法");
    },
     getData(){
        alert(this.state.msg);
    },
    getMessage(){
       alert(this.state.message);
    },
    getName=()=>{
        alert(this.state.username);
    },
    //  改变this指向方式二:
    setData=()=>{
        // 改变state的值
        this.setState({
            msg:'我是一个home组件 这是改变后的值'
        });
    },
        setName=(str)=>{
        // 改变state的值
        this.setState({
            username:str
        });
       },
    render(){
        return(
            <div>
                <h2>{this.state.msg}</h2>
                <h2>{this.state.username}</h2>
                <button onClick={this.run}>执行方法</button>
                <br/>
                  //  改变this指向方式三(通过bind):
                <button onClick={this.getData.bind(this)}>第一种改变this指向的方法</button>
                <br/>
                <button onClick={this.getMessage}>第二种改变this指向的方法</button>
                <br/>
                <button onClick={this.getName}>第三种改变this指向的方法</button>
                <br/>
                <button onClick={this.setData}>改变state里面的值</button>
                <br/>
                <button onClick={this.setName.bind(this,张三")}>改变state里面的值(通过传值方式)</button>
            </div>
        )
    }
}

React 键盘事件 表单事件 事件对象以及React中的ref获取dom节点 、React实现类似Vue的双向数据绑定】

class Home extends React.Component{
    constructor(props){
        super(props);   //固定写法
        this.state={
            msg:'我是一个home组件',
            username:''
        }   
    },
    run=(event)=>{
        // alert(event.target);   /*获取执行事件的dom节点*/
        event.target.style.background='red';
        //获取dom的属性
        alert(event.target.getAttribute('aid'))
    },
    inputChange=(e)=>{
        //获取表单的值
        console.log(e.target.value);
        // let val=this.refs.username.value; // 通过ref方式
        let val=e.target.value//  通过时间对象方式
        this.setState({
            username:val
        })
    },
    getInput=()=>{
        alert(this.state.username);
    },
    //键盘弹起事件
    inputKeyUp=(e)=>{
        console.log(e.keyCode);
        if(e.keyCode==13){// 如果是回车键
            console.log(e.target.value);
        }
    },
   //键盘按下去事件
    inputonKeyDown=(e)=>{
        if(e.keyCode==13){ // 如果是回车键
           console.log(e.target.value);
        }
    },
    render(){
        return(
            <div>              
               {this.state.msg}
               {/* 事件对象 */}
               <h2>事件对象演示</h2>
               <button aid="123" onClick={this.run}>事件对象</button>
               <br /><br /> <hr />
                <h2>表单事件</h2>
                {/* 
                    获取表单的值
                    1、监听表单的改变事件                        onChange
                    2、在改变的事件里面获取表单输入的值           事件对象
                    3、把表单输入的值赋值给username              this.setState({})
                    4、点击按钮的时候获取 state里面的username     this.state.username
                 */}
                <input ref="username" aid="123" onChange={this.inputChange}/> <button onClick={this.getInput}>获取input的值</button>
                 <br /><br/> 
                <h2>键盘事件</h2>
                <input onKeyUp={this.inputKeyUp}/>
                <br /><br />
                <input onKeyDown={this.inputonKeyDown}/>
            </div>
        )
    }
}

React表单详解 约束性和非约束性组件 input text checkbox radio  select  textarea  以及获取表单的内容

input的defaultValue 和value区别:

  • 非约束的:defaultValue,和react无关联,一般只用于展示,model和view不互相改变时候用
  • 约束的: value,这样就会和react关联,一版model和view(mv) 互相改变时候用
import React, { Component } from 'react';
class ReactForm extends Component {
    constructor(props) {
        super(props);
        this.state = {  
            msg:"react表单",
            name:'',  
            sex:'1',     
            city:'',      
            citys:[
                '北京','上海','深圳'            
            ],
            hobby:[   
                {  
                    'title':"睡觉",
                    'checked':true
                },
                {  
                    'title':"吃饭",
                    'checked':false
                },
                {  
                    'title':"敲代码",
                    'checked':true
                }
            ],
            info:''   
        };
        this.handleInfo=this.handleInfo.bind(this);
    },
    // 表单提交
    handelSubmit=(e)=>{
            //阻止submit的提交事件
            e.preventDefault();
            console.log(this.state.name,this.state.sex,this.state.city,this.state.hobby,this.state.info);

    },
    handelName=(e)=>{
        this.setState({
            name:e.target.value
        })
    },
    handelSex=(e)=>{
        this.setState({
            sex:e.target.value
        })
    },
    handelCity=(e)=>{
        this.setState({
            city:e.target.value
        })
    },
    handelHobby=(key)=>{
        var hobby=this.state.hobby;
        hobby[key].checked=!hobby[key].checked;
        this.setState({
            hobby:hobby
        })
    },
    handleInfo(e){
        this.setState({
            info:e.target.value
        })
    },
    render() {
        return (
            <div>
                <h2>{this.state.msg}</h2>
                <form onSubmit={this.handelSubmit}>
                 用户名:  <input type="text" value={this.state.name}  onChange={this.handelName}/> <br /><br />
                    性别:  <input type="radio" value="1" checked={this.state.sex==1}  onChange={this.handelSex}/>男
                           <input type="radio"  value="2" checked={this.state.sex==2}  onChange={this.handelSex}/><br /><br />

                居住城市:   <select value={this.state.city} onChange={this.handelCity}>
                                {
                                    this.state.citys.map(function(value,key){
                                        return <option key={key}>{value}</option>
                                    })
                                }
                            </select> <br />
                    爱好:   
                            {
                                // 复选框ing
                                this.state.hobby.map((value,key)=>{
                                  **return (**
**<span key={key}>**
**<input type="checkbox"  checked={value.checked}  onChange={this.handelHobby.bind(this,key)}/> {value.title}**
**</span>**
**)**
                                })
                            }
                    <br />
                  备注:<textarea value={this.state.info}  onChange={this.handleInfo} />
                 <input type="submit"  defaultValue="提交"/>
                </form>
            </div>
        );
    }
}
export default ReactForm;

React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法

父给子传值和方法

父:
<Header
 name='首页'  
 msg={this.state.msg}
 run={this.run}
 that={this}></Header>
子:
this.props.msg  //
this.props.run() // 调用父组件方法
this.props.that  // 获取整个父组件 (this.props.that.run()也能执行父组件方法)

父调子的方法或取值:

通过this.$refs

React  propTypes  defaultProps

父组件给子组件传值:     

  1. defaultProps:父子组件传值中,如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值
  2. propTypes:验证父组件传值的类型合法性           
1.引入import PropTypes from 'prop-types';            

2.类.propTypes = { 

       namePropTypes.string             

    };    

 defaultProps和propTypes都是定义在子组件里面

父组件

import React, { Component } from 'react';
import Header from './Header';
class Home extends Component {
    constructor(props){
        super(props);        
        this.state={
          title:'首页组件',
          count:20
        }
    },
    render() {
      return (
        <div>
            {/* <Header/>  */}
            <Header **title={this.state.title}**  **num={this.state.count}**  />
        </div>
      );
    }
}
子组件
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Header extends Component  **{**
    constructor(props) {
        super(props);
        this.state = {
            msg:"我是一个头部组件"
         };
    },
    render() {
        return (
            <div>
                <h2>---{this.props.title}--- {this.props.num}</h2>
            </div>
        );
    }
**}**
// defaultProps   如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值
Header.defaultProps={
   title:'标题'
}
//同行propTypes定义父组件给子组件传值的类型
Header.propTypes={
   num:PropTypes.number
}
export default Header;

React 获取数据 axios插件 fetch-jsonp插件的使用

1.axios

cnpm  install axios --save

import axiosfrom "axios"
axios.get("https://baidu.com")
    .then((res)=>{})
    .chatch((err)=>{})

2.fetch-jsonp

cnpm install fetch-jsonp --save

import fetchJsonp from "fetch-jsonp"
fetchJsonp("https://baidu.com")
    .then((res)=>{   return res.json();})
    .then((json)=>{ console.log(json);})
    .chatch((err)=>{})

React 生命周期函数

组件加载的时候触发的函数:(按执行顺序)

constructor,
componentWillMount,
render,
componentDidMount

数据更新的时候触发的生命周期函数:

shouldComponentUpdate,   //  是否要更新数据,如果return false,componentWillUpdate和render和componentDidUpdate将不再执行
shouldComponentUpdate
componentWillUpdate, // 将要更新数据的时候触发
render,   // 渲染
componentDidUpdate  //  组件数据更新完成
你在父组件里面改变props传值的时候触发的:
componentWillReceiveProps
组件销毁的时候触发的:
componentWillUnmount

React路由 react-router4.x的基本配置

cnpm  install  react-router-dom  --save

exact标识严格匹配.

 [比如下面的例子,如果不加exact,访问的路径是'/new'时,Home和News组件两个都会加载]

import {BrowserRouter as Router,Route,Link} from "react-router-dom"
<link to="/">首页</link>
<link to="/news">分享</link>
<link to="/product">商品</link>
<router exact path="/" component={Home} />
<router exact path="/news" component={News} />
<router exact path="/product" component={Product} />

React路由 react-router4.x 动态路由以及get传值 React中使用url模块

1.动态路由传参(参数在url中)
<router exact path="/detail/:id" component={Product} />
<link  to={`/content/${变量id}`}>{跳转详情}</link>
通过this.props.match.params获取参数
2.get方式传参(参数在查询参数里)
获取查询参数方式一:
**url模块来解析url地址**,
cnpm install url --save,    
import url from 'url'
console.log(url.parse(location.search));
console.log(url.parse(this.props.location.search)); // react中
获取查询参数方式二:
自己写js获取
3.通过localStorage传参

react-router4.x中使用js跳转路由

js跳转路由

//1. 引入
import {BrowserRouter as Router,Route,Link,Redirect,withRouter} from "react-router-dom"
// 2.定义一个flag
this.state = {
    loginFlag:false
}
// 3.render里面判断flag来决定是否跳转
render(){
    if(this.state.loginFlag){
        // 方式一:
        return <Redirect to={{pathname:"/"}}/>;
        // 方式二:
        return <Redirect to="/">;
    }
    return(
        <div>登录页面的表单</div>
    )
}
// 4,要执行js跳转
    通过js 改变loginFlag的状态
    改变以后重新render就可以Redirect自己来跳转(通过第三步的redirect来跳转的)

react-router4.x路由的嵌套

通过Link跳转 <link to="路径">
通过Route 通过url承载组件<Route   path=''路径' component={组件名}>
// this.props.match.url是父级路由
<Route exact path={` **${this.props.match.url}** /` component="Children1"}
<Route path={`${this.props.match.url}/add` component="Children2"}

React react-router4.x中实现路由模块化、以及嵌套路由父子组件传值

就是类似于vue那种路由单独写到一个json里面 ,用jsx硬拼 路由放到json里面:

image.png 嵌套父子组件传值方式:

image.png 子路由里面获取子路由数据遍历:

通过this.props.routers就能拿到子路由所以路由

React UI框架Antd(Ant Design)的使用

antdesign官网:ant.design/docs/react/…

1,安装antd 
    cnpm  install  antd --save
2、在您的react项目的css文件中引入 Antd的css
    @import '~antd/dist/antd.css';
3、看文档使用:
    如使用Button:
    import { Button } from 'antd';
    <Button type="primary">Primary</Button>

react配置按需加载Antd的css

React中使用Antd高级配置,按需引入css样式
    我们现在已经把组件成功运行起来了,但是在实际开发过程中还有很多问题,例如上面的例子实际上加载了全部的 antd 组件的样式(对前端性能是个隐患)。
   1、安装antd     
        cnpm install antd --save
   2、安装(react-app-rewired)一个对 create-react-app 进行自定义配置的社区解决方案
       cnpm install  react-app-rewired --save


   3、修改 package.json
   react-scripts 需改为react-app-rewired
          "scripts": {
            "start": "react-app-rewired start",
            "build": "react-app-rewired build",
            "test": "react-app-rewired test --env=jsdom",
            "eject": "react-app-rewired eject"
          }
   4、安装babel-plugin-import   babel-plugin-import是一个用于按需加载组件代码和样式的 babel 插件
         cnpm install babel-plugin-import --save
   5、在项目根目录创建一个 config-overrides.js 配置文件
       const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
config = injectBabelPlugin(

['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }],
config,
);
return config;
};
 7、然后移除前面在 src/App.css 里全量添加的 @import '~antd/dist/antd.css'; 直接引入组件使用就会有对应的css
        import { Button } from 'antd';
        <Button type="primary">Primary</Button>