React知识点总结

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kanghui_898/article/details/94737806

1、安装

1、必须安装nodejs稳定版本,exe直接安装即可,安装完既有npm;
2、安装cnpm/yarn淘宝镜像:

 npm install -g cnpm --registry=https://registry.npm.taobao.org
 cnpm install -g yarn

3、安装vscode;

2、创建项目:

1、安装脚手架:

cnpm install -g create-react-app

2、cd进入想要创建项目的目录,创建项目:

 create-react-app reactdemo

3、运行项目:

cnpm start /yarn start

4、生成项目: 

cnpm run build  /  yarn build

3、目录结构分析

1、node_modules:安装模块目录
2、public:公共目录,一般无需修改,里面有index.html入口文件;
3、重点关注src目录!
 3.1、index.js:react入口文件,React是react核心库,ReactDOM是提供与DOM相关的功能;
 3.2、index.css:react项目公共css,可以删掉;
 3.3、registerServiceWorker.js  加快react运行速度的js文件;
 3.3、App.js 组建
 
4、项目配置文件:package.json
5、yarn.lock yarn临时文件,不用管;

默认生成的结构比较乱,可手动整理目录结构:
1、新建components组建文件夹,用于存放组建,组建名称首字母大写!
2、新建assets文件夹,用于存放静态文件;
  2.1、新建assets/image文件夹,放图片;
  2.2、新建assets/css文件夹,放静态文件;

4、代码编写

1、引入组建,无需写后缀名js:

import Home from './components/Home'

快速构建组建框架代码:

1、在vscode应用商店中安装插件 :

     React-Native/React/Redux snippets for es6/es7

2、在vscode中输入cccs,按enter即可;

2、数据定义,写在构造函数里面:

import React from 'react'
 class Home extends React.Component{
  constructor(props){
   super(props);  //固定写法,用于父子组建传值;
   this.state={
    name:"111",
    age:'20'
   }
  }
  render(){
   return(
    <div>
     name:{this.state.name}  //引用数据;
    </div>
   )
  }
 }

3、绑定css属性用

   class--->className
   for---->htmlFor
   style属性和以前的写法有些不一样:

<div style={{'color':'blue'}}>{this.state.title}</div>
<div style={{'color':this.state.color}}>{this.state.title}</div>

4、引入图片,要用模块化方式
    法1:

 import image1 from '../assets/image/1.jpg'
 <img src={image1}/>


 法2:

 <img src = {require('../assets/image/1.jpg')}/>

引入远程图片,直接src写地址即可;

 

 
5、写事件

 run=()=> {
     alert(this.state.name)
   }
 <button onClick={this.run}>按钮</button>
 事件传值:
  <button onClick={this.setName.bind(this,'张三')}>执行方法传值</button>
 
  setName=(str)=>{
        this.setState({
            username:str
        })
    }

6、事件对象

 <button aid="123" onClick={this.run}>事件对象</button>
  run=(event)=>{
        event.target.style.background='red';
        alert(event.target.getAttribute('aid'))//获取dom的属性
    }


7、表单事件
 法1:

{/* 获取表单的值   
    1、监听表单的改变事件                        onChange
   2、在改变的事件里面获取表单输入的值           事件对象
   3、把表单输入的值赋值给username              this.setState({})
   4、点击按钮的时候获取 state里面的username     this.state.username
 */}
  <input onChange={this.inputChange}/>
  <button onClick={this.getInput}>获取input的值</button>
  
  inputChange=(e)=>{
   this.setState({
    username:e.target.value
   })
  }

 getInput=()=>{
   alert(this.state.username);
  }


  法2:

 {/* 获取表单的值   
    1、监听表单的改变事件                        onChange
   2、在改变的事件里面获取表单输入的值            ref获取
   3、把表单输入的值赋值给username              this.setState({})
   4、点击按钮的时候获取 state里面的username     this.state.username
    */}
   <input ref="username" onChange={this.inputChange}/>
   <button onClick={this.getInput}>获取input的值</button>
   
   
    inputChange=()=>{
    let val=this.refs.username.value;
    this.setState({
     username:val
    })
   }
   getInput=()=>{
    alert(this.state.username);
   }
   

8、键盘事件

 <input onKeyUp={this.inputKeyUp}/>
 //键盘事件
    inputKeyUp=(e)=>{
        if(e.keyCode==13){
            alert(e.target.value);
        }
    }

9、约束性和非约束性组件

约束性和非约束性组件:

非约束性组件:

<input type="text" defaultValue="a" />   这个 defaultValue 其实就是原生DOM中的 value 属性。
 这样写出的来的组件,其value值就是用户输入的内容,React完全不管理输入的过程。

约束性组件:

<input value={this.state.username} type="text" onChange={this.handleUsername}  />
   这里,value属性不再是一个写死的值,他是 this.state.username, this.state.username 是由 this.handleChange 负责管理的。
   这个时候实际上 input 的 value 根本不是用户输入的内容。而是onChange 事件触发之后,由于 this.setState 导致了一次重新渲染。不过React会优化这个渲染过程。看上去有点类似双向数据绑定
      
 

10、数据持久化

//执行缓存数据
localStorage.setItem('todolist',JSON.stringify(tempList));


//获取缓存的数据

var todolist=JSON.parse(localStorage.getItem('todolist'));   /*字符串*/

11、React的模块化封装Storage

新建文件夹model,存放自定义模块,新建model/storage.js模块:

var storage={


    set(key,value){

        localStorage.setItem(key,JSON.stringify(value));
    },
    get(key){

        return JSON.parse(localStorage.getItem(key));

    },remove(key){

        localStorage.removeItem(key)
    }
};

export default storage;

引用:

//引入自定义模块
import storage from '../model/storage';

 //执行缓存数据           
storage.set('todolist',tempList);


 //获取缓存的数据
var todolist=storage.get('todolist');  

11、React中父子组建传值

React中的组件: 解决html 标签构建应用的不足。

使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入。

父子组件:组件的相互调用中,我们把调用者称为父组件,被调用者称为子组件

父组件给子组件传值

      1.在调用子组件的时候定义一个属性  <Header msg='首页'></Header>

      2.子组件里面 this.props.msg         

说明:父组件不仅可以给子组件传值,还可以给子组件传方法,以及把整个父组件传给子组件。

父组件主动获取子组件的数据

        1、调用子组件的时候指定ref的值   <Header ref='header'></Header>     
        2、通过this.refs.header  获取整个子组件实例

12、默认值和类型检验

defaultProps:父子组件传值中,如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值

    propTypes:验证父组件传值的类型合法性

            1、引入import PropTypes from 'prop-types';

            2、类.propTypes = {
                name: PropTypes.string
            };

都是定义在子组件里面

//defaultProps   如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值
Header.defaultProps={

    title:'标题'
}

//同行propTypes定义父组件给子组件传值的类型

Header.propTypes={

    num:PropTypes.number
}

13、获取数据

react获取服务器APi接口的数据:

react中没有提供专门的请求数据的模块。但是我们可以使用任何第三方请求数据模块实现请求数据

1、axios          https://github.com/axios/axios  

 axios的作者觉得jsonp不太友好,推荐用CORS方式更为干净(后端运行跨域)

 1、安装axios模块npm install axios  --save   /  npm install axios  --save

 2、在哪里使用就在哪里引入import axios from 'axios'

 3、看文档使用

var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20';

            axios.get(api)
            .then(function (response) {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            });

import React, { Component } from 'react';


import axios from 'axios';

class Axios extends Component {
    constructor(props) {
        super(props);
        this.state = { 

            list:[]
         };
    }

    getData=()=>{


        //通过axios获取服务器数据

        var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20';   //接口后台允许了跨域

        axios.get(api)
        .then((response)=> {
            console.log(response.data.result);

            //用到this要注意this指向
            this.setState({

                list:response.data.result

            })
        })
        .catch(function (error) {
            console.log(error);
        });


    }
    render() {
        return (

            <div>
                <h2>axios获取服务器数据</h2>
                <button onClick={this.getData}>获取服务器api接口数据</button>
                <hr />
                <ul>
                    {
                        this.state.list.map((value,key)=>{
                            return <li key={key}>{value.title}</li>
                        })
                    }   
                </ul>
            </div>
        );
    }
}

export default Axios;

 

2、fetch-jsonp    https://github.com/camsong/fetch-jsonp

1、安装 npm install fetch-jsonp  --save

2、import fetchJsonp from 'fetch-jsonp'

3、看文档使用

            fetchJsonp('/users.jsonp')
            .then(function(response) {
              return response.json()
            }).then(function(json) {
              console.log('parsed json', json)
            }).catch(function(ex) {
              console.log('parsing failed', ex)
            })

import React, { Component } from 'react';
import fetchJsonp from 'fetch-jsonp';

class FetchJsonp extends Component {
    constructor(props) {
        super(props);
        this.state = {

            list:[]
        };
    }

    getData=()=>{

         //获取数据

        var api="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20";
        fetchJsonp(api)
        .then(function(response) {
            return response.json()
        }).then((json)=> {
            // console.log(json);
            
            this.setState({

                list:json.result
            })

        }).catch(function(ex) {
            console.log('parsing failed', ex)
        })
    }
    render() {
        return (
            <div>
                <h2>FetchJsonp 获取服务器jsonp接口的数据</h2>
                <button onClick={this.getData}>获取服务器api接口数据</button>
                <hr />
                <ul>
                    {
                        this.state.list.map((value,key)=>{
                            return <li key={key}>{value.title}</li>
                        })
                    }                       
                </ul>
            </div>  
        );
    }
}

export default FetchJsonp;

3、其他请求数据的方法也可以...自己封装模块用原生js实现数据请求也可以...

14、生命周期函数

React生命周期函数:

    组件加载之前,组件加载完成,以及组件更新数据,组件销毁。

    触发的一系列的方法 ,这就是组件的生命周期函数

组件加载的时候触发的函数:

    constructor 、componentWillMount、 render 、componentDidMount

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

    shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate

你在父组件里面改变props传值的时候触发的:

    componentWillReceiveProps

组件销毁的时候触发的:

    componentWillUnmount

必须记住的生命周期函数:

   *加载的时候:componentWillMount、 render 、componentDidMount(dom操作)

    更新的时候:componentWillUpdate、render、componentDidUpdate

    *销毁的时候: componentWillUnmount

15、路由配置

/*
  react路由的配置:
    1、找到官方文档 https://reacttraining.com/react-router/web/example/basic

    2、安装  cnpm install react-router-dom --save


    3、找到项目的根组件引入react-router-dom

       import { BrowserRouter as Router, Route, Link } from "react-router-dom";

    4、复制官网文档根组件里面的内容进行修改  (加载的组件要提前引入)


         <Router>

                <Link to="/">首页</Link>

                <Link to="/news">新闻</Link>

                <Link to="/product">商品</Link>


               <Route exact path="/" component={Home} />
               <Route path="/news" component={News} />    
               <Route path="/product" component={Product} />   
         </Router>


         exact表示严格匹配


react动态路由传值

      1、动态路由配置

          <Route path="/content/:aid" component={Content} />   

      2、对应的动态路由加载的组件里面获取传值

            this.props.match.params.aid


      跳转:<Link to={`/content/${value.aid}`}>{value.title}</Link>

react get传值  
    
      1、路由配置
            <Route path="/productcontent" component={ProductContent} />
      
      2、获取 this.props.location.search,其值为: ?aid=4

         然后使用url模块解析字符串,安装  cnpm install url --save
            import url from 'url'
            var aid = url.parse(this.props.location.search,true).query.aid

      跳转:<Link to={`/productcontent/?aid=${value.aid}`}>{value.title}</Link>
         
*/

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

import './assets/css/index.css'

import Home from './components/Home';
import News from './components/News';
import Product from './components/Product';
import Content from './components/Content';

import ProductContent from './components/ProductContent';

class App extends Component {

  render() {
    return (
        <Router>
          <div>           

              <header className="title">
              
                <Link to="/">首页</Link>

                <Link to="/news">新闻</Link>

                <Link to={`/productcontent/?aid=${value.aid}`}>{value.title}</Link>

              </header>


               <br />
               <hr />
      
               <br />
      
      
              <Route exact path="/" component={Home} />
              <Route path="/news" component={News} />    
              <Route path="/product" component={Product} /> 
              <Route path="/productcontent" component={ProductContent} />

              <Route path="/content/:aid" component={Content} />                 
          </div>
      </Router>
    );
  }
}

export default App;

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

/*

实现js跳转路由:https://reacttraining.com/react-router/web/example/auth-workflow

1、要引入Redirect

    import {
    BrowserRouter as Router,
    Route,
    Link,
    Redirect,
    withRouter
    } from "react-router-dom";

2、定义一个flag
        this.state = { 
                loginFlag:false            
        };

3、render里面判断flag 来决定是否跳转

        if(this.state.loginFlag){

            return <Redirect to={{ pathname: "/" }} />;
        }

4、要执行js跳转

        通过js改变loginFlag的状态

        改变以后从新render 就可以通过Redirect自己来跳转


*/

import React, { Component } from 'react';

import {Redirect} from "react-router-dom";


class Login extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            loginFlag:false            
        };
    }

    doLogin=(e)=>{

        e.preventDefault();
        

        let username=this.refs.username.value;

        let password=this.refs.password.value;


        console.log(username,password)

        if(username=='admin' && password=='123456'){

            //登录成功   跳转到首页

            this.setState({

                loginFlag:true
            })



        }else{

            alert('登录失败')
        }

    }
    render() {


        if(this.state.loginFlag){

            // return <Redirect to={{ pathname: "/" }} />;

            return <Redirect to='/' />;
        }
        return (    


            <div>
                 <br /> <br /> <br />

                <form onSubmit={this.doLogin}>

                        <input type="text"  ref="username" />  <br /> <br />

                        <input type="password"  ref="password" /> <br /> <br />

                         <input type="submit"  value="执行登录"/>

                </form>

               

            </div>
            
        );
    }
}

export default Login;

17、路由的嵌套

import React, { Component } from 'react';

import { BrowserRouter as Router, Route, Link } from "react-router-dom";


import Info from './User/Info';
import Main from './User/Main';

class User extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            msg:'我是一个User组件'
         };
    }    
    render() {
        return (
            <div className="user">
               

               <div className="content">


                   <div className="left">

                        <Link to="/user/">个人中心</Link>

                        <br />
                        <br />

                        <Link to="/user/info">用户信息</Link>


                    </div>

                    <div className="right">

                            
                            <Route exact path="/user/" component={Main} />

                            <Route  path="/user/info" component={Info} />

                    </div>


               </div>


            </div>
        );
    }
}

export default User;

18、路由模块化代码分离

新建model/router.js文件:


import Home from '../components/Home';
import User from '../components/User';
import Shop from '../components/Shop';
import News from '../components/News';


let routes = [
    {
      path: "/",
      component: Home,
      exact:true
    },
    {
      path: "/shop",
      component: Shop
    },
    {
      path: "/user",
      component: User
    },
    {
      path: "/news",
      component: News
    }
];

export default routes;

App.js中声明路由:

import React, { Component } from 'react';

import { BrowserRouter as Router, Route, Link } from "react-router-dom";


import './assets/css/index.css';

import routes from './model/router.js';

class App extends Component {

  render() {
    return (

      <Router>
        <div>
            <header className="title">

                <Link to="/">首页组件</Link>
                <Link to="/user">用户页面</Link>
                <Link to="/shop">商户</Link>
                <Link to="/news">新闻</Link>
            </header> 

            {
              routes.map((route,key)=>{

                  if(route.exact){

                    return <Route key={key} exact path={route.path} component={route.component}/>
                  }else{
                    return <Route  key={key}  path={route.path} component={route.component}/>

                  }
              })
            }            
         
        </div>
      </Router>
    );
  }
}

export default App;

19、路由模块化嵌套路由


import Home from '../components/Home';
import User from '../components/User';
    import UserList from '../components/User/UserList';
    import UserAdd from '../components/User/UserAdd';
    import UserEdit from '../components/User/UserEdit';
import Shop from '../components/Shop';
import News from '../components/News';


let routes = [
    {
      path: "/",
      component: Home,
      exact:true
    },
    {
      path: "/shop",
      component: Shop
    },
    {
      path: "/user",
      component: User,  
      routes:[   /*嵌套路由*/
        {
          path: "/user/",
          component: UserList
        },
        {
          path: "/user/add",
          component: UserAdd
        },
        {
          path: "/user/edit",
          component: UserEdit
        }
      ]
    },
    {
      path: "/news",
      component: News
    }
];

export default routes;

App.js,给嵌套路由传递路由参数:


import React, { Component } from 'react';

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

import './assets/css/index.css';

import routes from './model/router.js';

class App extends Component {

  render() {
    return (

      <Router>
        <div>
            <header className="title">

                <Link to="/">首页组件</Link>
                <Link to="/user">用户页面</Link>
                <Link to="/shop">商户</Link>
                <Link to="/news">新闻</Link>
            </header> 


            {
              routes.map((route,key)=>{

                  if(route.exact){

                    return <Route key={key} exact path={route.path}                     

                    // route.component     value.component   <User  {...props}  routes={route.routes} />

                    render={props => (
                      // pass the sub-routes down to keep nesting
                      <route.component {...props} routes={route.routes} />
                    )}

                    />
                  }else{
                    return <Route  key={key}  path={route.path} 
                    render={props => (
                      // pass the sub-routes down to keep nesting
                      <route.component {...props} routes={route.routes} />
                    )}
                    />

                  }
              })
            }            
          
         
        </div>
      </Router>
    );
  }
}

export default App;

User.js根据传递的路由参数实现路由:

import React, { Component } from 'react';

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

class User extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            msg:'我是一个User组件'
         };
    }
    componentWillMount(){

        console.log(this.props.routes);
    }
    render() {
        return (
            <div className="user">               
               
               <div className="content">

                    <div className="left">

                        <Link to="/user/">用户列表</Link>

                        <br />
                        <br />

                        <Link to="/user/add">增加用户</Link>


                         <br />
                        <br />

                        <Link to="/user/edit">编辑用户</Link>

                    </div>

                    <div className="right">
                            {

                                this.props.routes.map((route,key)=>{

                                     return   <Route key={key} exact path={route.path} component={route.component} />
                                })
                            }

                            {/* <Route  path="/user/add" component={UserAdd} /> */}

                    </div>

                    </div>

            </div>
        );
    }
}
export default User;

 

展开阅读全文

没有更多推荐了,返回首页