React 笔记

  • A+
所属分类:Web前端
摘要

<div id=”app”></div><!– React核心库 –><script crossorigin src=”https://unpkg.com/react@16/umd/react.development.js”></script>

基础

<div id="app"></div>

<!-- React核心库 -->

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>

<!-- React操作DOM库 -->

<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<!-- jsx -->

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

<!-- jsx需要添加属性type="text/babel" -->

<script type="text/babel"></script>

// 渲染DOM方法 ReactDOM.render(要渲染的元素,要渲染的位置)

// 创建DOM方法 React.createElement(标签名,标签属性,标签内容)

ReactDOM.render(

    React.createElement('mark',null,'内容'),

    document.getElementById('app')

)

 

let p = 'p';

let pAttr = {className: 'p1 p2',title: '22'}

let oP = React.createElement(p,pAttr,'content')

let root = document.getElementById('app')

ReactDOM.render(oP,root)

脚手架

安装脚手架 cnpm i -g create-react-app

创建项目   create-react-app demo

 

import logo from './logo.svg';  // 引入图片

import './App.css';  // 引入css

组件

函数式组件

function App() {

  return ( <div className="App"></div> );

}

 

import React from 'react';

类组件  继承React.Component

class ComA extends React.Component{

    render(){

        return (

            <div>React组件</div>

        )

    }

}

React中组件首字母必须为大写,小写会被识别为元素DOM标签

 

父传子

<Com name={this.state.age}/>

function Com(){

    return <div>{this.props.name}</div>

}

 

子传父  --- 父发送方法给子组件调用传参

<SonCom getSonData={this.getSonData}/>

<button onClick={() => {this.props.getSonData('sonVal')}}>click</button>

 

兄弟传值

A --- 父 --- B

父组件传给A函数, A调用方法,方法修改数据,数据传给B

getSonData = msg => {

    this.setState({msg})

}

<SonCom getSonData={this.getSonData}/>

<SonCom1 msg={this.state.msg}/>

A

<button onClick={() => {this.props.getSonData('sonVal')}}>click</button>

B

<div>{this.props.msg}</div>

事件处理

修改状态需要用 setState({修改的属性:值},回调)

onClick={()=>{this}} 箭头函数指向react

onClick={this.fn.bind(this)} 普通函数指向类本身,需要bind绑定

或声明函数时

getData = () => {

    console.log(this);

}

类  ----

constructor() {

    super()

    this.state = {

        tag : true,

        arr : ['z1','z2'],

        age : 10

    }

}

render ----

{ this.state.age }

<button onClick={

    () => { this.setState({ age: this.state.age + 1 }, 

            ()=>{console.log(this.state.age)}) 

    }

}

>age++</button>

 

事件对象

es5方式 event会隐式传递, es6手动传递ev。接收形参都在函数的最后一个参数

<button onClick={this.getEvent.bind(this,11)}>getEventES5</button>

<button onClick={(ev) => this.getEvent(11,ev)}>getEventES6</button>

 

模拟Vue双向绑定

valChange = (e) => {

    this.setState({

        txt : e.target.value

    })

}

<input type="text" value={this.state.txt} onChange={this.valChange}/>

<div>{this.state.txt}</div>

生命周期

componentWillMount(){

    console.log('将要渲染');

}

componentDidMount(){

    console.log('渲染完成');

}

componentWillReceiveProps(newProps){

    console.log(newProps,'父组件传过来的新值');

}

shouldComponentUpdate(newProps,newState){

    console.log(newProps,'父组件更改的新值');

    console.log(newState,'新state');

    console.log(this.state,'旧的state');

    console.log('组件是否更新');

    return true // 返回false则不更新

}

componentWillUpdate(){

    console.log('即将更新');

}

componentDidUpdate(){

    console.log('更新完成');

}

componentWillUnmount(){

    console.log('移除DOM前');

}


获取原生DOM节点

<p ref='p1'>p1</p>

<p ref={el => this.p2 = el}>p2</p>

推荐第三种

<p ref={this.p3}>p3</p>

constructor() {

    super()

    this.p3 = React.createRef();

}

路由

配置

npm install react-router-dom -S

import {BrowserRouter} from 'react-router-dom'

index.js 用BrowserRouter包裹 APP

ReactDOM.render(

  <BrowserRouter>  // HashRouter 会有 /#/  BrowserRouter则没有

    <App />

  </BrowserRouter>,

  document.getElementById('root')

);

新建Router.js

// 引入路由组件

import { Switch, Route } from 'react-router-dom';

// 引入页面

import ComA from './ComA'

 

return (

    <div>

        <Switch>

            /* exact严格匹配 否则其他页面也会匹配 / */

            <Route path='/' component={ComA} exact></Route>

            <Route path='/comb' component={ComB} ></Route>

        </Switch>

    </div>

);

APP组件

// 引入创建的router组件

import Router from './Router'

return (

    <div className="App">

       <Router className="App" />   

    </div>

)

导航

import {Link} from 'react-router-dom'

<Link to='/' > 返回首页 </Link>

 

增强版

import {NavLink} from 'react-router-dom'

<NavLink to='/' activeClassName={this.props.location.pathname =='/' && 'active-link'}> 返回首页</NavLink>

NavLink才有activeClassName , 但是其他组件的样式会被 / 匹配到

 

this.props.location.path获取当前地址

 

编程式导航

this.props.history.push(url)

this.props.history.replace()

this.props.history.go()

this.props.history.goBack()

this.props.history.goForward()

动态路由

React的嵌套路由是在父组件中配置的

import {Switch, Route ,Redirect  } from 'react-router-dom'

<Switch>

     Redirect 重定向  exact 精确匹配,

    <Redirect path='/big' exact to='/big/small1' ></Redirect>

    <Route path='/big/small1/:参数名字' component={Small1}></Route>

</Switch>

 

this.props.match.params.参数名字 接参

 

state 是保密的, 也可以 键为query   search 则会在地址栏显示

<NavLink to={{pathname:'/big/small2',state:{name:'参数'}}} <NavLink />

 

配置代理

根目录新建setupProxy.js   安装http-proxy依赖

const proxy = require('http-proxy-middleware');

module.exports = function (app) {

    app.use(proxy.createProxyMiddleware(

        "/api", {

            target: "http://localhost:3000",

            changeOrigin: true,

            pathRewrite: {

                "^/api": ""

            }

        })

    );

};