react笔记

创建项目

方法一:先全局安装npm i create-react-app -gcreate-react-app myreact
方法二:npx create-react-app myreact

function组件

import React from 'react'
import ReactDom from 'react-dom'
var name = 'bzw';

/*react组件都是函数*/
/*
  结构中变量都用 {} 包起来
  组件中根元素  只能由一个根标签   但是可以是一个空标签
  结构中不能有关键字   class => calssName  for => htmlFor
  结构中不能直接把对象  作为儿子; 若是数组直接把拼接的结果扔到了结果中
  循环结构一般使用map

*/

function mymap(ary){
    let t = [];
    for(var i = 0;i < ary.length; i++){
      t.push(<li key={i+10}>{ary[i]}</li>)
    }
    return t;
}
function List(){
    var obj = {a:12,b:13};
    var h1 = <h1>哈哈</h1>;
    var ary = [1,2,3];
    // var ary2 = [<i>1</i>,<i>2</i>,<i>3</i>]
     
    return <ul className="box">
        {
          ary.map(item=>{
              return <li key={item}>{item}</li>
          })
        }
        {mymap(ary)}
        <li>{name}</li>
        <li>{obj.a}</li>
        <li>{h1}</li>
        <li>{JSON.stringify(obj)}</li>
        <li>{ary}</li>
        {/* <li>{ary2}</li> */}
        <li><input type="checkbox" name="" id="qqq"/><label htmlFor="qqq">9999</label>
        </li>
    </ul>
}


ReactDom.render(<>
    <h2>我的react</h2>
    {/* 在react的结构模板中,想要使用变量   需要用 {变量和表达式} 包起来*/}
    {name}
    <List></List>
</>,document.querySelector('#root')

)

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

// 组件首字母必须大写

//用function一般称为静态组件或者函数式组件 
function App666(props) {  
    console.log(arguments);
    return (<div>
       <p style={{color:props.style}}>123</p>
    </div>)
}

function H1() {  
    return <h1>家哈哈</h1>
}

// 凡是在组件上使用的行内属性都是自定义属性
//  在原生html上标签使用的都是react规定的

ReactDom.render(<>
                <App666 className="box1" id={666} qqq={622} style="red"/>
                <H1/>
                </>,document.getElementById("root"))

class组件

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

console.log(React.Component);
// 在class组件中,结构是通过rander函数返回结果决定的
class App extends React.Component{
    // 创造一个APP类,继承React.Component这个类
    // constructor(props){   //接收值
    //     // 在class声明类的时候,写了constructor  必写super() =>  相当于call继承
    //     super(props)
    // }
    render(){
        console.log(this.props);
        // this.props中的属性只读,不能改
       return <div>啦啦啦</div>
    }
}


ReactDom.render(<App className123='box'/>,document.getElementById("root"))

状态和属性

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

// react组件只有两个数据源:  一个是属性props;    另一个state
class App extends React.Component{
    constructor(){   //接收值
        super()
        this.state = {
            // 这里放当前组件的私有属性
            name:"zhangsan",
            time:new Date().toLocaleString(),
        }
    }
    // 想让视图更新:   react规定需要调用setState这个方法,也就是让render函数执行
    // 在render中   不能写setState  这个方法执行,会触发死循环
    componentDidMount(){
        // 当组件的DOM渲染完成后  会触发这个函数
        setInterval(() =>{
            this.setState({
                // 也就是主动触发双向数据绑定
                time:new Date().toLocaleString()
            })
        })
    }
    render(){
       let {className} = this.props;
       let {name, time} = this.state;
       return <div className={className}>
         {name}
         <h2>{time}</h2>
       </div>
    }
}


ReactDom.render(<App className='box'/>,document.getElementById("root"))

事件

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

// 属性:从外部传过来的    状态(state):自己定义的
// 类组件
class App extends React.Component{
    // constructor(){   
    //     super()
    //     this.state = {
    //       count:100
    //     }
    // }
    state = {
        count: 100,
        aa:20
    }
    add(n,e){
        console.log(e.nativeEvent,e.target);
        // console.log("+")
        // console.log(this);
        this.setState({
            count: this.state.count+n
        })
    }
    minus(e,n){
        console.log(e);
        console.log(n);
        // console.log("-");
        // setStste更新数据  大部分  是异步操作
        // 在  原生事件绑定中  或者  定时器  中总是同步的
        this.setState({
            count: this.state.count-n,
            aa:this.state.aa-1
        },function () {  
            // 数据更新之后触发
            // console.log(this.state.count);
        })
    }
    minus2=(e)=>{
        // console.log(this);
        console.log(e);
        this.setState({
            count: this.state.count+1
        })
    }
    over(){
        // console.log("over");
    }
    componentDidMount(){
      
    }
    render(){
        let {count} = this.state
       return <div className=''>
           {/* on+事件名   事件名遵循  驼峰命名  合成时间(就是原生事件) */}
            <button onClick={this.add.bind(this)}>+</button>
            {/* bind的返回结果给了onClick,这里一旦bind之后this就改不了了  (不能用call,call直接让函数执行,返回了执行结果;bind返回的是函数体吧)*/}
            <button onClick={this.add.bind(this,10)}>+10</button>
            <button onClick={this.add.bind(this,100)}>+100</button>

            <button onClick={(e)=>{this.minus(e,10)}}>-10</button>   
            {/* 把箭头函数给了onClick ,箭头函数的作用域就是上级作用域的this,上级作用域就是render*/}

            <button onClick={this.minus2}>---</button>   

    <h2 onMouseOver={this.over}> {count}  {this.state.aa}</h2>
       </div>
    }
}


ReactDom.render(<App/>,document.getElementById("root"))

useState

import React from 'react';
import ReactDom from 'react-dom';
import { useState } from 'react';

// function组件(函数是组件   静态组件)

// 更新比较少使用函数是组件    多的话用类组件
/* function App (){
    let [count,setCount] = useState(10);
    let [name,setName] = useState("张三")
    function add(){
        let t = count + 100
        setCount(t)   //更新count   并且触发视图更新 {setState({count:t})}
        // console.log(count);
    }
    return <div>
       <button onClick={add}>+</button>

       <button onClick={()=>{setName("啦啦啦啦")}}>+</button>
       {count}
       {name}
    </div>
} */

function App (){
    let [state,setState] = useState({
        count:100,
        name:"zhang"
    })
    function add(){
       let t = state.count+10
       let obj= {
            ...state,
            count:t
        }
       setState(obj)
    }
    function miuns(){
        let t = state.count-10
        setState({
            ...state,
            count:t
        })
    }
    function setName11(){
        setState({
            ...state,
           name:"哈哈哈"
       })
    }
    return <div>
       <button onClick={add}>+</button>
       <button onClick={miuns}>---</button>

       <button onClick={setName11}>+</button>
       {state.count}
       {state.name}
    </div>
}

ReactDom.render(<App/>,document.getElementById("root"))

子父组件

import React, { Component } from 'react';
import ReactDom from 'react-dom';
// import propTypes from "prop-types"   //用来处理传进来的数据的情况
import qqq from "prop-types"

// 子传父:通过事件参数传递
// 父传子: props

// 限制传进来的数据的情况

class Button extends Component{
    static propTypes = {
        // className:qqq.string ,  //className必须是个字符串   规定单个数据类型
        className: qqq.oneOfType([                       //规定多个数据类型
            qqq.string,
            qqq.number,
          ]).isRequired,  //必传
    }
    
    state={
        name:"woshizizujian"
    }
    click=()=>{
        this.props.onClick123 && this.props.onClick123()
        this.props.onChangeName && this.props.onChangeName(this.state.name)

    }

    // 给默认值的
    // static defaultProps = {
    //     className: 'qqqqqqqq'
    // }; 
    render(){
        let {className="qqq",onClick123,children="hahahh",} = this.props   //children:字符串,数组,对象(单个节点(标签)虚拟DOM)
        // return <button className={className} onClick={onClick123}>{children}</button>
        return <button className={className} onClick={this.click}>{children}</button>

    }
}
class App extends React.Component{
    constructor(){   
        super()
        this.state = {
           name:"zhangsan",
           className:"box"
        }
    }
    fn=()=>{
        // console.log(e);
        console.log(666);
        this.setState({
            name:"zhufengpeixun"
        })
    }
    qqq=(name)=>{
        this.setState({
            name:name
        })
    }
    render(){
       return <div className=''>
           <Button className={this.state.className}><i>222</i></Button>
           <Button onClick123={this.fn}/>{this.state.name}
           <Button onChangeName={this.qqq}/>
       </div>
    }
}


ReactDom.render(<App/>,document.getElementById("root"))

ref

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

/* 
   获取DOM元素或组件
        ref不能获取函数是组件
        ref="xxx"  this.refs.zzz    将要废弃
        ref = {(el)=>{this.xxx = el}}   this.xxx
        this.xxx = React.createRef()     this.xxx.current */
class App extends React.Component{
    constructor(){   
        super()
        this.www = React.createRef()
        this.state = {
  
        }
    }
    fn=()=>{
        console.log(this.refs.aaa);
        console.log(this.qqq);
        console.log(this.www.current);
    }
    render(){
       return <div className=''>
           <button onClick={this.fn}>按钮</button>
           <p className="qqq" ref="aaa">6666</p>
           <p className="qqq" ref={(el)=>{this.qqq=el}}>6666</p>
           <p ref={this.www}>6666</p>
           
       </div>
    }
}


ReactDom.render(<App/>,document.getElementById("root"))

钩子函数

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

class Page1 extends React.Component{
    componentWillUnmount(){
        console.log("page1销毁");
    }
    render(){
        return <h1>page1</h1>
    }

}
class Page2 extends React.Component{
    componentWillUnmount(){
        console.log("page2销毁");
    }
    render(){
        return <h1>page2</h1>
    }

}
// 钩子函数:某个阶段执行某个对应的函数
class App extends React.Component{
    constructor(){   //第一个钩子函数:初始化
        super()
        this.state = {
           name:"4568",
           type:"page1"
        }
    }
/*     static getDerivedStateFromProps(props,state){
        // 主要目的:把props中的属性合并到state(实际上是把这个函数返回的东西合并到state中)
        // props:父组件传来的数据
        // state:就是自己的数据
        // 这个函数必须返回一个对象
        console.log(props,state);
        return {
            ...props,
            aaa:123456
        }

    } 
    componentWillMount(){
        // 类似于beforemount   
        // DOM渲染完成之前,可以同步更改     将要被废弃的一个钩子函数
        this.state.name = 9999
        console.log();
    }
    componentDidMount(){
        // DOM渲染完成后执行的钩子函数
        // 操作DOM(echerts   百度地图)
        // 发送ajax请求
    }
    // componentWillReceiveProps(newProps){
    //     // 当父组件传进来的数据更新时触发     将要被废弃的一个钩子函数
    // }
    shouldComponentUpdate(newProps,newState){
        // 这个钩子函数可以用来控制组件是否更新
        // 可以用来提升组件的渲染效率,是用来优化的钩子函数
        return false
    }
    componentDidUpdate(prevProps,prevState){
        // DOM更新完成后触发
    }
    componentWillUnmount(){
        // 组件销毁前
    } */
    // PureComponent    唇组件    写这个就不用写shouldComponentUpdate()了
    /*  特点:会自动进行新老props校验,也就是会自动执行shouldComponentUpdate
              只会进行一层校验
      */
    render(){
        console.log(6666);
        let {type} = this.state
        console.log(this.state);

       return <div className=''>
           {this.state.name}

           <button onClick={()=>{this.setState({type:"page1"})}}>page1</button>
           <button onClick={()=>{this.setState({type:"page2"})}}>page25</button>

           {
               type == "page1"?
               <Page1/>:
               <Page2/>
           }

       </div>
    }
}


ReactDom.render(<App/>,document.getElementById("root"))

useEffect

import React,{useEffect,useState} from 'react';
import ReactDom from 'react-dom';
// state 是为了让函数式组件使用  setState
// useEffect 是为了让函数式组件使用钩子函数

function App() {  
    let [count,setCount] = useState(100)
    let [name,setName] = useState("珠峰")

    useEffect(()=>{   
        //类似于componentDidMount和componentDidUpdate的结合体
        // 可以通过第二个人参数来决定啥时候执行
        console.log(count);
        // console.log(name);
    },[count])

    useEffect(()=>{   
       //  个数不限制    比如想在name发生改变时触发
        console.log(name);
        // console.log(name);
    },[name])
    useEffect(()=>{   
        // 传参为空数组,表示只在初次加载时使用
     },[])
    return <div>
        hello
        <button onClick={setCount.bind(null,count+1)}>改变</button>
      <h1>{count}</h1>

      <button onClick={()=>{setName("珠峰培训")}}>改变</button>
      <h1>{name}</h1>
    </div>
}


ReactDom.render(<App/>,document.getElementById("root"))

router

import React from 'react';

import ReactDom from 'react-dom';
import {BrowserRouter, HashRouter, Link, NavLink, Route, Switch, Redirect} from "react-router-dom"
// BrowserRouter  利用的是 H5 的history  Api;  对比vue就是history  利用的是popState
// HashRouter 利用的是  hashChange;            对比vue是hash模式  
// 项目中  我们需要使用其中一个把根组件抱起来
//Link  相当于 vue  的 router-link  用来跳转对应路径(to属性跟的值)
// NavLink 用法 = Link  比Link多一个类名
// Route  相当于  vue  的 router-view  用来展示对应的哪个组件
// Switch  用这个组件把用到的route抱起来   可以避免react每一个route都去匹配的情形
// Redirect 重定向
// 在react  我们可以使用search  或者  params的方式进行参数传递
//  若是search  通过loaction.search  或者this.props.location.search
//  若是params  我们需要在编写Route组件的时候  /xxx/:属性名,  调用的时候  通过this.props.match.params获取   参数少

// react中路由懒加载  npm i react-loadable
// import Home from "./component/home"
// import User from "./component/uaer"
import Loadable from 'react-loadable';

const Home = Loadable({
    loader: () => import(/*webpackChunkName:"home"*/'./component/home'),
    loading: ()=><h3>正在加载</h3>,
});
const User = Loadable({
    loader: () => import(/*webpackChunkName:"user"*/'./component/uaer'),
    loading: ()=><h3>正在加载</h3>,
});


let Temp = ()=><h1>啦啦啦</h1>
class App extends React.Component{
    constructor(){   
        super()
        this.state = {
  
        }
    }
    render(){
       return <div className=''>
           <Link to="/home/666">首页</Link>
           <Link to="/user">用户</Link>
           <NavLink to="/home/777">首页</NavLink>
           <NavLink to="/user?qqq=123&aaa=456">用户</NavLink>
           <Switch>
              {/* <Route path="/" exact component={Temp}>哈哈哈哈</Route> */}
              {/* exact是一个精确匹配  只有路径 与 path的值 完全相等 才可*/}

              <Redirect path="/" exact to="/home"></Redirect>
              {/* 当前路径如果是/  则重定到/home */}

              <Route path="/home/:qqq" component={Home}></Route>
              <Route path="/user" component={User}></Route>
              <Route path="/*">404</Route>
           </Switch>

           

           
       </div>
    }
}


ReactDom.render(
<HashRouter>
<App/>
</HashRouter>,document.getElementById("root"))

// 传参:方法传参、隐形传参、路径参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值