绑定属性
class 要变成 className
for 要变成 htmlFor
style属性和以前的写法有些不一样
<div style={{'color':'blue'}}>{this.state.title}</div>
<div style={{'color':this.state.color}}>{this.state.title}</div>
循环数据要加key,组件的构造函数中一定要注意 super
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象
constructor(props){
super(props); /*用于父子组件传值 固定写法*/
this.state={
userinfo:'张三',
}
}
绑定事件处理函数this的几种方法:
第一种方法:
run(){
alert(this.state.name)
}
<button onClick={this.run.bind(this)}>按钮</button>
第二种方法:
构造函数中改变
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>
表单事件-双向绑定
run=(event)=>{
event.target.style.background='red';
//获取dom的属性
alert(event.target.getAttribute('aid'))
this.setState({
username:e.target.value
});
/*
获取dom节点
1、给元素定义ref属性
<input ref="username" />
2、通过this.refs.username 获取dom节点
*/
let val=this.refs.username.value;
this.setState({
username:val
})
}
//键盘事件
inputKeyUp=(e)=>{
if(e.keyCode==13){
alert(e.target.value);
}
}
{/* model改变影响View view改变反过来影响model */}
只需实现onChange事件,defaultValue={};
表单
//阻止submit的提交事件刷新页面
e.preventDefault();
handelHobby=(key)=>{
var hobby=this.state.hobby;
//取反
hobby[key].checked=!hobby[key].checked;
this.setState({
hobby:hobby
})
}
爱好:
{
// 注意this指向
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>
)
})
}
约束性和非约束性组件:
非约束性组: 这个 defaultValue 其实就是原生DOM中的 value 属性。
这样写出的来的组件,其value值就是用户输入的内容,React完全不管理输入的过程。
约束性组件:
这里,value属性不再是一个写死的值,他是 this.state.username, this.state.username 是由 this.handleChange 负责管理的。
这个时候实际上 input 的 value 根本不是用户输入的内容。而是onChange 事件触发之后,由于 this.setState 导致了一次重新渲染。不过React会优化这个渲染过程。看上去有点类似双向数据绑定
storage缓存数据
//storage只能保存字符串》先将数组转字符串
localStorage.setItem(key,JSON.stringify(value));
return JSON.parse(localStorage.getItem(key));
localStorage.removeItem(key);
//生命周期函数 页面加载就会触发
componentDidMount(){
//获取缓存的数据
var todolist=storage.get('todolist');
if(todolist){
this.setState({
list:todolist
})
}
}
父子组件传值
React中的组件: 解决html 标签构建应用的不足。
父组件给子组件传值
1.在调用子组件的时候定义一个属性
2.子组件里面 this.props.msg 可以给子组件传方法,以及把整个父组件传给子组件。
<button onClick={this.props.news.getChildData.bind(this,‘我是子组件的数据’)}>子组件给父组件传值
父组件主动获取子组件的数据
1、调用子组件的时候指定ref的值
2、通过this.refs.header 获取整个子组件实例 (dom(组件)加载完成以后获取 )
defaultProps: 父子组件传值中,如果父调用子不传值,在子中使用defaultProps定义默认值
Header.defaultProps={ //类名.defaultProps
title:'标题'
}
propTypes:验证父组件传值的类型合法性
1、引入import PropTypes from ‘prop-types’;
类.propTypes = {//p小写
name: PropTypes.string//number 大写
};
react中没有提供专门的请求数据的模块。可以使用任何第三方请求数据实现
1、axios https://github.com/axios/axios axios的作者觉得jsonp不太友好,推荐用CORS方式更为干净(后端运行跨域)
1、安装axios模块 cnpm install axios --save / cnpm install axios --save
2、在哪里使用就在哪里引入 import axios from ‘axios’
3、看文档使用
var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20';
axios.get(api)
.then((response)=> {
//用到this要注意this指向
this.setState({
list:response.data.result
})
})
.catch(function (error) {
console.log(error);
});
2、fetch-jsonp https://github.com/camsong/fetch-jsonp
1、安装 npm install fetch-jsonp --save
2、import fetchJsonp from ‘fetch-jsonp’
3、看文档使用
fetchJsonp(api)
.then(function(response) {
return response.json()
}).then((json)=>{
this.setState({
list:json.result
})
}).catch(function(ex) {
console.log('parsing failed', ex)
})
生命周期函数
React生命周期函数:
组件加载之前,组件加载完成,以及组件更新数据,组件销毁。
触发的一系列的方法 ,这就是组件的生命周期函数
组件加载触发的函数:构造》组件将要挂载的》渲染》组件挂载完成
constructor 、componentWillMount、 render 、componentDidMount(dom结束)
组件数据更新发的生命周期函数:
shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
你在父组件里面改变props传值的时候触发的:
componentWillReceiveProps 定义在子组件中
组件销毁的时候触发的:
componentWillUnmount 定义在被销毁的组建中
//是否要更新数据 如果返回true才会执行更新数据的操作
shouldComponentUpdate(nextProps, nextState){
console.log(nextProps);
console.log(nextState);
return true;
}
react路由的配置:
1、找到官方文档 https://reacttraining.com/react-router/web/example/basic
2、安装 cnpm install react-router-dom --save
3、找到项目的根组件引入react-router-dom
import { BrowserRouter as Router, Route, Link } from “react-router-dom”;
4、复制官网文档根组件里面的内容进行修改 (加载的组件要提前引入)
<Router>
<Link to="/">首页</Link>
<Link to="/news">新闻</Link>
<Link to="/product">商品</Link>
<Route exact path="/" component={Home} />
<Route path="/news" component={News} />
<Route path="/product" component={Product} />
</Router>
exact表示严格匹配
动态路由传值:
1、动态路由配置
2、对应的动态路由加载的组件里面获取传值
this.props.match.params
跳转:
<Link to={/content/${value.aid}
}>{value.title} //es6模板字符串
get传值:
1、获取 this.props.location.search
跳转:
<Link to={/productcontent?aid=${value.aid}
}>{value.title}
路由嵌套
<Link to="/shop/">商户列表</Link>
<Link to="/shop/add">增加商户</Link>
/*获取父级路由地址*/
<Route exact path={`${this.props.match.url}/`} component={ShopList} />
<Route path={`${this.props.match.url}/add`} component={ShopAdd} />
父组件传值:render
{
routes.map((route,key)=>{
if(route.exact){
return <Route key={key} exact path={route.path}
render={props => (
<route.component {...props} routes={route.routes} />
)}/>
}else{
return <Route key={key} path={route.path}
render={props => (
<route.component {...props} routes={route.routes} />
)}/>
}
})
}
模块化分离
let routes = [
{
path: "/",
component: Home,
exact:true
},
{
path: "/user",
component: User,
routes:[ /*嵌套路由*/
{
path: "/user/",
component: UserList
}
]
}
];
export default routes;