react学习笔记

创建项目

1.安装脚手架Create React App

npm install -g create-react-app

2.创建项目

create-react-app reactapp(项目名称可以自定义)

React Jsx

1、JSX执行更快,编译为JavaScript代码时进行优化

2、类型更安全,编译过程如果出错就不能编译,及时发现错误

注意:

1、JSX必须要有根节点。

2、正常的普通HTML元素要小写。如果是大写,默认认为是组件。

JSX表达式

1、中间如果需要插入变量用{}

2、{}中间可以使用表达式

3、{}中间表达式中可以使用JSX对象

4、属性和html内容一样都是用{}来插入内容

5.绑定属性注意:
class 要变成 className

for 要变成 htmlFor

style属性和以前的写法有些不一样:

{this.state.title}
{this.state.title}

React组件

函数式组件与类组件的区别和使用,函数式比较简单,一般用于静态没有交互事件内容的组件页面。类组件,一般又称为动态组件,那么一般会有交互或者数据修改的操作。

1、函数式组件
function Childcom(props){

console.log(props)

let title = <h2>我是副标题</h2>

let weather = props.weather

//条件判断 

let isGo = weather=='下雨' ?"不出门":"出门"

return (<div>

<h1>函数式组件helloworld</h1>

{title}

 <div>

是否出门?

<span>{isGo}</span>

</div>

</div>

)

}
2.类组件
class HelloWorld extends React.Component{

constructor(props) {

  super(props);

}

render(){

return (<div>

<h1>类组件定义HELLOWORLD</h1>

<h1>hello:{this.props.name}</h1>

<Childcom weather={this.props.weather} />

</div>

)

}

}

注意:

1、组件的构造函数中一定要注意 super,子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象

constructor(props){
        super(props);  /*用于父子组件传值  固定写法*/

        this.state={

            userinfo:'张三'
        }
    }

2、组件名称首字母大写、组件类名称首字母大写

3、为什么官方的列子里面写个super(props):只有一个理由需要传递props作为super()的参数,那就是你需要在构造函数内使用this.props

那官方提供学习的例子中都是写成super(props),所以说写成super(props)是完全没问题的,也建议就直接这样写。

4.React是单项数据流,父组件改变了属性,那么子组件视图会更新。

5.属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改

6.构造函数的作用:

用来新建父类的this对象;子类必须在constructor方法中调用super方法;否则新建实例时会报错;因为子类没有自己的this对象;
而是继承父类的this对象,然后对其进行加工。如果不调用super方法;子类就得不到this对象。

state和props的区别

假如我们有个父组件,可以在父组件的state里定义子组件的数据比如:

this.setState({ childData: 'Child Data' });  

紧接着,在父组件的render()方法里面,可以将父组件的state,作为子组件的props传递下去,如下

<Child data = {this.state.childData}/>

这样就可以父组件的state传递给子组件的props。从子组件的角度来看,props是不可变的。如何改变子组件的props?我们仅仅需要改变父组件内部的state即可,父组件的state改变之后,引起父组件重新渲染,在渲染的过程中,子组件的data变成父组件this.state.childDtat的值。这样父组件内部state改变,就会引起子组件的改变。

这样就形成里从上而下的数据流,也就是React常说的单向数据流,这个“向”是向下。
我们常常利用这个原理更新子组件,从而衍生出一种模式,父组件:处理复杂的业务逻辑、交互以及数据等。子组件:称它为Stateless组件即无状态组件,只用作展示。在我们开发过程中,尽可能多个使用无状态组件,可以缕清业务之间的逻辑关系,提高渲染效率。

如果子组件想要改变自身的data,这时候需要,父组件传递给子组件一个方法,改变父组件自身的state
父组件:

<Child data={this.state.childData} handleChange={this.handelChildChange}></Child>

子组件接收父组件方法
let Chilid = ({data,handleChange}) =>

{data.name}

绑定事件处理函数this的3种方法

第一种方法:
	run(){

        	alert(this.state.name)

  	}
  	<button onClick={this.run.bind(this)}>按钮</button>

第二种方法:
 //构造函数中改变
 constructor(props) {
        super(props);
     this.run = this.run.bind(this);
       
    }
 	run(){

       	alert(this.state.name)

 	 }

 	<button onClick={this.run>按钮</button>
第三种方法:
//箭头函数
	 run=()=> {
			alert(this.state.name)

 	 }

	<button onClick={this.run}>按钮</button>


react中父子组件传值

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

父子组件传值:

父组件给子组件传值

​ 1.在调用子组件的时候定义一个属性

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

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

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

​ 1、调用子组件的时候指定ref的值


​ 2、通过this.refs.header 获取整个子组件实例

注意:props可以传递函数,props可以传递父元素的函数,就可以去修改父元素的state,从而达到传递数据给父元素。

父传子数据传递案例:
//父组件
class Father extends React.Component {

    constructor(props) {
        super(props);
        this.state = { 
            msg:"首页信息",
            title:"首页头部"            
         };
    }
    run=()=>{
        alert("我是父组件的run方法");
    }
    getData=()=>{
        alert(this.state.title);

    }
    //获取子组件传过来的值
    getChilddata=(result)=>{
        alert(result);

    }
    //父组件主动调用子组件的数据和方法
    getHeader=()=>{
        alert(this.refs.Header.state.msg);//获取子组件的数据
        this.refs.Header.run();    //获取子组件的方法
    }
    render() {
        return (<div>
            <Header ref='Header' title={this.state.title} run={this.run} Father={this}></Header>
            <hr></hr>
            {this.state.msg}
            <hr></hr>
           <button onClick={this.getHeader}>父组件主动调用子组件的数据和方法</button>
        </div>
          
        );
    }
}

//子组件
class Header extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = { 
                data:'lzx',
                msg:"子组件信息"
             };
        }
       
    
    run=()=>{
        alert('子组件方法');
    }
   
   getFather=()=>{
       alert(this.props.Father.state.title);
   } 
    render() {
        return (
        <div>{this.props.title}
        <br/>
          <button onClick={this.props.run}>调用父组件run方法</button> 
          <br></br>       
          <button onClick={this.props.Father.getData}>调用父组件的getData方法</button>   
          <br></br>   
          <button onClick={this.getFather}>获取整个father实例</button> 
          <br></br>  
          <button onClick={this.props.Father.getChilddata.bind(this,this.state.data)}>父组件中获取子组件传过来的值</button> 
        </div>
        );
    }
}


react生命周期函数

组件加载之前,组件加载完成,以及组件更新数据,组件销毁。 触发的一系列的方法 ,这就是组件的生命周期函数

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

constructor 、componentWillMount、 render 、componentDidMount

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

shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate

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

componentWillReceiveProps

组件销毁的时候触发的:

componentWillUnmount

必须记住的生命周期函数:
加载的时候:componentWillMount、 render 、componentDidMount(dom操作)
更新的时候:componentWillUpdate、render、componentDidUpdate
销毁的时候: componentWillUnmount
class Lifecycle extends React.Component {
    constructor(props) {
        console.log('1.构造函数');
        super(props);
        this.state = { 
            msg:'我是一个msg'
         };
    }
    //组件将要挂载触发的生命周期函数
    componentWillMount(){
        console.log('2.组件将要挂载');
    }
    //组件挂载完成触发的生命周期函数
    componentDidMount(){
        //dom操作放在这里面    请求数据也放在这里面
        console.log('4.组件挂载完成');
    }
    //是否要更新数据
    shouldComponentUpdate(nextProps,nextState){
        console.log('01.是否要更新数据');
        console.log(nextProps);
        console.log(nextState);
    
        return true;
    }
    //组件将要更新时触发
    componentWillUpdate(){
        console.log('02.组件数据将要更新');
    }
    //组件更新完成
    componentDidUpdate(){
        console.log('03.组件数据更新完成');
    }
    setMsg=()=>{
        this.setState({
            msg:"我是改变后的msg"
        })
    }
    //组件销毁时触发的生命周期函数  用在组件销毁时执行操作
    componentWillUnmount(){
        console.log('组件销毁了');
    }

    //
    componentWillReceiveProps(){
        console.log('父子组件传值,父组件里面改变了props的值触发的方法');
    }
    render() {
        console.log('3.数据渲染');
        
        return (
            <div>
                生命周期函数演示----{this.state.msg}----{this.props.title}
                <br></br>
                <button onClick={this.setMsg}>改变msg</button>
            </div>
        );
    }
}

React 路由

安装:npm install react-router-dom --save

ReactRouter三大组件:

Router:所有路由组件的根组件(底层组件),包裹路由规则的最外层容器。

属性:basename->设置跟此路由根路径,router可以在1个组件中写多个。

Route:路由规则匹配组件,显示当前规则对应的组件

Link:路由跳转的组件

注意:如果要精确匹配,那么可以在route上设置exact属性。

//Router使用案例
import React from 'react';
//hash模式
//import {HashRouter as Router,Link,Route} from 'react-router-dom'

//history模式/后端匹配使用
import {BrowserRouter as Router,Link,Route} from 'react-router-dom'

function Home(){
    return (
        <div>
            <h1>admini首页</h1>
        </div>
    )
}

function Me(){
    return (
        <div>
            <h1>admin个人中心</h1>
        </div>
    )
}

function Product(){
    return (
        <div>
            <h1>admin产品页面</h1>
        </div>
    )
}

class App extends React.Component{
    
    render(){
        return (
            <div id="app">
                {/* <div>所有页面普通内容</div> */}
                <Router>
                    <Route path="/" exact component={()=>(<div>首页</div>)}></Route>
                    <Route path="/me" component={()=>(<div>me</div>)}></Route>
                    <Route path="/product" component={()=>(<div>product</div>)}></Route>
                </Router>

                <Router>
                     <div className="nav">
                        <Link to="/">Home</Link>
                        <Link to="/product">Product</Link>
                        <Link to="/me">个人中心</Link>
                    </div> 
                    <Route path="/" exact component={Home}></Route>
                    <Route path="/product" component={Product}></Route>
                    <Route path="/me" exact component={Me}></Route>
                </Router>
            </div>
        )
    }
}

React中使用Antd

1、安装antd npm install antd --save / yarn add antd / cnpm install antd --save

2、在您的react项目的css文件中引入 Antd的css

​ @import ‘~antd/dist/antd.css’;

3、看文档使用:

​ 如使用Button:

​ 1、在对应的组件中引入Antd import { Button } from ‘antd’;

2、<Button type="primary">Primary</Button>

Antd按需引入

我们现在已经把组件成功运行起来了,但是在实际开发过程中还有很多问题,例如上面的例子实际上加载了全部的 antd 组件的样式(对前端性能是个隐患)。

1、安装antd npm install antd --save

2、安装(react-app-rewired)一个对 create-react-app 进行自定义配置的社区解决方案
yarn add react-app-rewired / 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、在项目根目录创建一个 config-overrides.js 用于修改默认配置

module.exports = function override(config, env) {

	 // do stuff with the webpack config...
 return config;
};

5、安装babel-plugin-import babel-plugin-import是一个用于按需加载组件代码和样式的 babel 插件

​ yarn add babel-plugin-import / cnpm install babel-plugin-import --save

6、修改 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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值