- A+
基础
<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": ""
}
})
);
};