创建react项目
全局安装create-react-app
cnpm install -g create-react-app
创建react项目方式一:
create-react-app reactdemo
创建react项目方式二:(版本要求node>=6 and npm>=5.2)
npx create-react-app reactdemo
jsx是html 和js混合模式
React 创建组件、绑定属性( 绑定class 绑定style)、引入图片 循环数组渲染数据
dom渲染变量
<div>{this.state.msg}</div> 类似于vue的<div>{{this.state.msg}}</div>
标签属性用变量
title={this.state.tite} 类似于vue的 :title="state.title"
dom添加class方式一:(写死)
<div className="red" ></div> 添加一个class
dom添加class方式二:(通过变量)
<div className={this.state.color} ></div> 添加一个class
dom的的for关键字用htmlFor代替
<label htmlFor="name">姓名</label>
<input id="name" />
行内样式
<div style={{"color":"red"}}></div>
<div style={this.state.stype}></div>
引入图片
import logo from './1.jpg'
<img src={logo}/>
<img src={require('./1.jpg')}/>
解析html
<div dangerouslySetInnerHTML={{_html:this.state.list.content}}></div>
渲染数组(三种方法)
class News extends React.Component{
constructor(props){
super(props);
this.state = {
list:[11111,22222,33333],
list2:[<h2 key='1'>我是一个h2</h2>,<h2 key='2'>我是一个h2</h2>],
list3:[
{title:"新闻1111"},
{title:"新闻2222"},
{title:"新闻3333"},
{title:"新闻4444"},
]
}
},
render(){
let listResult = this.state.list.map(function(value,key){
return <li key={key}>{value}</li>
})
return(){
<div className="news">
{this.state.list2}
<hr/>
<ul>{listResult}</ul>
<hr/>
<ul>
{
this.state.list3.map(function(value<key){
return (<li key={key}>{value.title}</li>);
})
}
</ul>
</div>
}
}
}
React事件 方法、 React定义方法的几种方式 获取数据 改变数据 执行方法传值
class Home extends React.Component{
constructor(props){
super(props);
this.state = {
msg:'我是一个home组件',
message:'我是一个message',
username:'itying',
}
// 改变this指向方式一:
this.getMessage = this.getMessage.bind(this);
},
run(){
alert("我是一个run方法");
},
getData(){
alert(this.state.msg);
},
getMessage(){
alert(this.state.message);
},
getName=()=>{
alert(this.state.username);
},
// 改变this指向方式二:
setData=()=>{
// 改变state的值
this.setState({
msg:'我是一个home组件 这是改变后的值'
});
},
setName=(str)=>{
// 改变state的值
this.setState({
username:str
});
},
render(){
return(
<div>
<h2>{this.state.msg}</h2>
<h2>{this.state.username}</h2>
<button onClick={this.run}>执行方法</button>
<br/>
// 改变this指向方式三(通过bind):
<button onClick={this.getData.bind(this)}>第一种改变this指向的方法</button>
<br/>
<button onClick={this.getMessage}>第二种改变this指向的方法</button>
<br/>
<button onClick={this.getName}>第三种改变this指向的方法</button>
<br/>
<button onClick={this.setData}>改变state里面的值</button>
<br/>
<button onClick={this.setName.bind(this," 张三")}>改变state里面的值(通过传值方式)</button>
</div>
)
}
}
React 键盘事件 表单事件 事件对象以及React中的ref获取dom节点 、React实现类似Vue的双向数据绑定】
class Home extends React.Component{
constructor(props){
super(props); //固定写法
this.state={
msg:'我是一个home组件',
username:''
}
},
run=(event)=>{
// alert(event.target); /*获取执行事件的dom节点*/
event.target.style.background='red';
//获取dom的属性
alert(event.target.getAttribute('aid'))
},
inputChange=(e)=>{
//获取表单的值
console.log(e.target.value);
// let val=this.refs.username.value; // 通过ref方式
let val=e.target.value; // 通过时间对象方式
this.setState({
username:val
})
},
getInput=()=>{
alert(this.state.username);
},
//键盘弹起事件
inputKeyUp=(e)=>{
console.log(e.keyCode);
if(e.keyCode==13){// 如果是回车键
console.log(e.target.value);
}
},
//键盘按下去事件
inputonKeyDown=(e)=>{
if(e.keyCode==13){ // 如果是回车键
console.log(e.target.value);
}
},
render(){
return(
<div>
{this.state.msg}
{/* 事件对象 */}
<h2>事件对象演示</h2>
<button aid="123" onClick={this.run}>事件对象</button>
<br /><br /> <hr />
<h2>表单事件</h2>
{/*
获取表单的值
1、监听表单的改变事件 onChange
2、在改变的事件里面获取表单输入的值 事件对象
3、把表单输入的值赋值给username this.setState({})
4、点击按钮的时候获取 state里面的username this.state.username
*/}
<input ref="username" aid="123" onChange={this.inputChange}/> <button onClick={this.getInput}>获取input的值</button>
<br /><br/>
<h2>键盘事件</h2>
<input onKeyUp={this.inputKeyUp}/>
<br /><br />
<input onKeyDown={this.inputonKeyDown}/>
</div>
)
}
}
React表单详解 约束性和非约束性组件 input text checkbox radio select textarea 以及获取表单的内容
input的defaultValue 和value区别:
- 非约束的:defaultValue,和react无关联,一般只用于展示,model和view不互相改变时候用
- 约束的: value,这样就会和react关联,一版model和view(mv) 互相改变时候用
import React, { Component } from 'react';
class ReactForm extends Component {
constructor(props) {
super(props);
this.state = {
msg:"react表单",
name:'',
sex:'1',
city:'',
citys:[
'北京','上海','深圳'
],
hobby:[
{
'title':"睡觉",
'checked':true
},
{
'title':"吃饭",
'checked':false
},
{
'title':"敲代码",
'checked':true
}
],
info:''
};
this.handleInfo=this.handleInfo.bind(this);
},
// 表单提交
handelSubmit=(e)=>{
//阻止submit的提交事件
e.preventDefault();
console.log(this.state.name,this.state.sex,this.state.city,this.state.hobby,this.state.info);
},
handelName=(e)=>{
this.setState({
name:e.target.value
})
},
handelSex=(e)=>{
this.setState({
sex:e.target.value
})
},
handelCity=(e)=>{
this.setState({
city:e.target.value
})
},
handelHobby=(key)=>{
var hobby=this.state.hobby;
hobby[key].checked=!hobby[key].checked;
this.setState({
hobby:hobby
})
},
handleInfo(e){
this.setState({
info:e.target.value
})
},
render() {
return (
<div>
<h2>{this.state.msg}</h2>
<form onSubmit={this.handelSubmit}>
用户名: <input type="text" value={this.state.name} onChange={this.handelName}/> <br /><br />
性别: <input type="radio" value="1" checked={this.state.sex==1} onChange={this.handelSex}/>男
<input type="radio" value="2" checked={this.state.sex==2} onChange={this.handelSex}/>女 <br /><br />
居住城市: <select value={this.state.city} onChange={this.handelCity}>
{
this.state.citys.map(function(value,key){
return <option key={key}>{value}</option>
})
}
</select> <br />
爱好:
{
// 复选框ing
this.state.hobby.map((value,key)=>{
**return (**
**<span key={key}>**
**<input type="checkbox" checked={value.checked} onChange={this.handelHobby.bind(this,key)}/> {value.title}**
**</span>**
**)**
})
}
<br />
备注:<textarea value={this.state.info} onChange={this.handleInfo} />
<input type="submit" defaultValue="提交"/>
</form>
</div>
);
}
}
export default ReactForm;
React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法
父给子传值和方法
父:
<Header
name='首页'
msg={this.state.msg}
run={this.run}
that={this}></Header>
子:
this.props.msg //
this.props.run() // 调用父组件方法
this.props.that // 获取整个父组件 (this.props.that.run()也能执行父组件方法)
父调子的方法或取值:
通过this.$refs
React propTypes defaultProps
父组件给子组件传值:
- defaultProps:父子组件传值中,如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值
- propTypes:验证父组件传值的类型合法性
1.引入import PropTypes from 'prop-types';
2.类.propTypes = {
name: PropTypes.string
};
defaultProps和propTypes都是定义在子组件里面
父组件
import React, { Component } from 'react';
import Header from './Header';
class Home extends Component {
constructor(props){
super(props);
this.state={
title:'首页组件',
count:20
}
},
render() {
return (
<div>
{/* <Header/> */}
<Header **title={this.state.title}** **num={this.state.count}** />
</div>
);
}
}
子组件
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Header extends Component **{**
constructor(props) {
super(props);
this.state = {
msg:"我是一个头部组件"
};
},
render() {
return (
<div>
<h2>---{this.props.title}--- {this.props.num}</h2>
</div>
);
}
**}**
// defaultProps 如果父组件调用子组件的时候不给子组件传值,可以在子组件中使用defaultProps定义的默认值
Header.defaultProps={
title:'标题'
}
//同行propTypes定义父组件给子组件传值的类型
Header.propTypes={
num:PropTypes.number
}
export default Header;
React 获取数据 axios插件 fetch-jsonp插件的使用
1.axios
cnpm install axios --save
import axiosfrom "axios"
axios.get("https://baidu.com")
.then((res)=>{})
.chatch((err)=>{})
2.fetch-jsonp
cnpm install fetch-jsonp --save
import fetchJsonp from "fetch-jsonp"
fetchJsonp("https://baidu.com")
.then((res)=>{ return res.json();})
.then((json)=>{ console.log(json);})
.chatch((err)=>{})
React 生命周期函数
组件加载的时候触发的函数:(按执行顺序)
constructor,
componentWillMount,
render,
componentDidMount
数据更新的时候触发的生命周期函数:
shouldComponentUpdate, // 是否要更新数据,如果return false,componentWillUpdate和render和componentDidUpdate将不再执行
shouldComponentUpdate
componentWillUpdate, // 将要更新数据的时候触发
render, // 渲染
componentDidUpdate // 组件数据更新完成
你在父组件里面改变props传值的时候触发的:
componentWillReceiveProps
组件销毁的时候触发的:
componentWillUnmount
React路由 react-router4.x的基本配置
cnpm install react-router-dom --save
exact标识严格匹配.
[比如下面的例子,如果不加exact,访问的路径是'/new'时,Home和News组件两个都会加载]
import {BrowserRouter as Router,Route,Link} from "react-router-dom"
<link to="/">首页</link>
<link to="/news">分享</link>
<link to="/product">商品</link>
<router exact path="/" component={Home} />
<router exact path="/news" component={News} />
<router exact path="/product" component={Product} />
React路由 react-router4.x 动态路由以及get传值 React中使用url模块
1.动态路由传参(参数在url中)
<router exact path="/detail/:id" component={Product} />
<link to={`/content/${变量id}`}>{跳转详情}</link>
通过this.props.match.params获取参数
2.get方式传参(参数在查询参数里)
获取查询参数方式一:
**url模块来解析url地址**,
cnpm install url --save,
import url from 'url'
console.log(url.parse(location.search));
console.log(url.parse(this.props.location.search)); // react中
获取查询参数方式二:
自己写js获取
3.通过localStorage传参
react-router4.x中使用js跳转路由
js跳转路由
//1. 引入
import {BrowserRouter as Router,Route,Link,Redirect,withRouter} from "react-router-dom"
// 2.定义一个flag
this.state = {
loginFlag:false
}
// 3.render里面判断flag来决定是否跳转
render(){
if(this.state.loginFlag){
// 方式一:
return <Redirect to={{pathname:"/"}}/>;
// 方式二:
return <Redirect to="/">;
}
return(
<div>登录页面的表单</div>
)
}
// 4,要执行js跳转
通过js 改变loginFlag的状态
改变以后重新render就可以Redirect自己来跳转(通过第三步的redirect来跳转的)
react-router4.x路由的嵌套
通过Link跳转 <link to="路径">
通过Route 通过url承载组件<Route path=''路径' component={组件名}>
// this.props.match.url是父级路由
<Route exact path={` **${this.props.match.url}** /` component="Children1"}
<Route path={`${this.props.match.url}/add` component="Children2"}
React react-router4.x中实现路由模块化、以及嵌套路由父子组件传值
就是类似于vue那种路由单独写到一个json里面 ,用jsx硬拼 路由放到json里面:
嵌套父子组件传值方式:
子路由里面获取子路由数据遍历:
通过this.props.routers就能拿到子路由所以路由
React UI框架Antd(Ant Design)的使用
antdesign官网:ant.design/docs/react/…
1,安装antd
cnpm install antd --save
2、在您的react项目的css文件中引入 Antd的css
@import '~antd/dist/antd.css';
3、看文档使用:
如使用Button:
import { Button } from 'antd';
<Button type="primary">Primary</Button>
react配置按需加载Antd的css
React中使用Antd高级配置,按需引入css样式
我们现在已经把组件成功运行起来了,但是在实际开发过程中还有很多问题,例如上面的例子实际上加载了全部的 antd 组件的样式(对前端性能是个隐患)。
1、安装antd
cnpm install antd --save
2、安装(react-app-rewired)一个对 create-react-app 进行自定义配置的社区解决方案
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、安装babel-plugin-import babel-plugin-import是一个用于按需加载组件代码和样式的 babel 插件
cnpm install babel-plugin-import --save
5、在项目根目录创建一个 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>