配置
首先建立react
项目最好是可以用webpack
做配置,为了兼容jsx
以及es6
的语法我们需要在配置里如下书写:
module.exports = {
module : {
loaders:[
{
test: /\.jsx?$/, // 用正则来匹配文件路径,匹配 js 或者 jsx
loader: 'babel',// 加载模块 babel-loader
query: {
presets: ['es2015', 'react']
}
}
]
}
}
React
react
这个框架的作用是创建组件
createElement(html,props,val)
创建一个虚拟DOM,返回的就是虚拟的DOM
// 创建一个虚拟DOM,第一个参数是创建标签的类型,名称。
// 第二个参数是标签属性用{}包起来。
// 第三个参数是标签中文本节点的内容,第三个参数也可以是一个子元素的或者多个子元素。
React.createElement("p",null,"你好");
在React创建组件时,对样式操作的注意点
1.在使用标签时class
这个属性为了避免和JS关键字冲突改为className
let Hehe = React.createClass({
render(){
return <div className="r">呵呵</div>
}
})
2.在使用内联样式时,可以将CSS
用JS
对象的方式书写
let Hehe = React.createClass({
render(){
let HeheCss = {
color:"blue"
}
return <p style={HeheCss}>红色</p>
}
})
ReactDOM.render(
<Hehe />,
document.getElementById("app")
)
React.createClass({render:fuction(){}})
创建一个组件,在render
中返回组件
组件化开发 用creatClass方法来开发一个组件 返回值是一个组件(重要 不可以直接使用) 可以用createElement的方法根据组件去创建虚拟Dom对象 根据render方法将虚拟Dom渲染到真正的Dome上,也可以直接调用ReactDOM.render
的函数,会自动指定render
函数,
var e = React.createClass({
// 在调用ReactDOM.render时调用
render:function(){
var e = React.createElement("p",{className:"red"},'helloreact');
Return e;
}
})
Var el = React.createElement(e);
React.render( el,document.querySelector("#content"));
ReactDOM.render(
<e />,
document.getElementById("app")
)
ref和refs直接操作DOM
在一个组件中所绑定的虚拟DOM
,有一个属性ref
可以给这个ref
设置一个值来作为标记,那么就可以在组件的这个对象中的属性refs
中直接获取标记的DOM
对象,通过.
语法方式。
let Hehe = React.createClass({
onclick(){
this.refs.text.innerHTML = "我这边改才是真的改";
},
render(){
let HeheCss = {
color:"blue"
}
console.log(this.props.isClick);
//return React.createElement("p",{className:"r"},'helloreact');
return <p ref='text' onClick={this.onclick} style={HeheCss}>{this.state.name}我的年龄是{this.state.age}</p>
}
})
组件的state属性
是一个对象,所有组件的属性都建议被放在这里。
getInitialState
组件初始化的时候会调用这个方法,返回的就是赋值给state
属性的对象
getInitialState(){
return {
name : "张三"
}
}
setState(obj)
刷新state
属性注意的是,如果对象的key
,与原先对象一样将会覆盖,如果有多余的就会合并,并刷新渲染组件。
this.setState({name:"李四",age:18})
State属性实例
let Hehe = React.createClass({
getInitialState(){
return {
name : "张三"
}
},
onclick(){
this.setState({name:"李四",age:18})
console.log(this.state)
},
render(){
let HeheCss = {
color:"blue"
}
console.log(this.props.isClick);
//return React.createElement("p",{className:"r"},'helloreact');
return <p onClick={this.onclick} style={HeheCss}>{this.state.name}我的年龄是{this.state.age}</p>
}
})
ReactDOM.render(
<Hehe isClick="true" />,
document.getElementById("app")
)
属性props
在创建虚拟DOM的时候添加属性,是以{}
的方式添加一个对象,在createClass
中我们是通过this.props.xx
来获取属性。在props
中是在标签中所有的属性值。
this.props.children
,显示组件双标签中的内容。
let Hehe = React.createClass({
render(){
let HeheCss = {
color:"blue"
}
console.log(this.props.isClick); // true
return <p style={HeheCss}>红色</p>
}
})
ReactDOM.render(
<Hehe isClick="true" />,
document.getElementById("app")
)
组件的生命周期:
componentWillMount()
即将加载时调用(只调用一次)
componentWillMount(){
console.log("即将加载");
}
componentDidMount()
初次完成时调用
componentDidMount(){
console.log("加载完成");
}
componentWillReceiveProps(nextProps)
在props更新前调用,初次加载时不会调用
componentWillReceiveProps(nextProps){
console.log("即将更新Props")
console.log(nextProps); // props 要更新的新对象
}
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate(nextProps, nextState){
// componentWillReceiveProps(nextProps) 在这个之后调用
console.log("即将重新渲染")
console.log(nextProps);
console.log(nextState);
return false; // 这个返回值来决定 是否要渲染
}
componentWillUpdate(nextProps, nextState)
shouldComponentUpdate(nextProps, nextState)
之后调用
componentWillUpdate(nextProps, nextState){
console.log("组件实例即将重新渲染时被调用")
console.log(nextProps);
console.log(nextState);
}
componentDidUpdate(prevProps, prevState)
componentWillUpdate(nextProps, nextState)
之后调用
componentDidUpdate(prevProps, prevState){
console.log("组件实例重新渲染后被调用")
console.log(prevProps); // 更新前的props
console.log(prevState); // 更新前的state
}
componentWillUnmount()
组件实例即将从DOM树移除时被调用
componentWillUnmount(){
console.log("组件实例即将从DOM树移除时被调用")
}
E6组件写法的注意事项:
1.getInitialState()
变为constructor()
里面通过this.state = {}
来赋值.
2.在设定类的时候记得继承React.Component
React-dom
将虚拟DOM转化为真实DOM
ReactDom.render(dom,element)
将左边虚拟的dom内容渲染到后边的dom树上,注意的是dom可以写成jsx语法的语法糖,魔法糖可以写成单闭合标签
let Hehe = React.createClass({
render(){
return <div>呵呵</div>
}
})
ReactDOM.render(
// 找到对应名称的组件
<Hehe />,
document.getElementById("app")
)
React Router
路由react组件,导入import {Router,Route,hashHistory} from 'react-router';
Router
外部包裹的路由标签
Route
定义路由的组件
hashHistory
切换路由
Router组件
history
属性,对应的就是导入的hashHistory
路由的切换由URL的hash变化决定。这个对应3个值。
hashHistory
路由将通过URL的hash部分切换。
browserHistory
需要后台做处理。
createMemoryHistory
服务器渲染。
ReactDOM.render(
<Router history = {hashHistory} >
</Router>,
document.getElementById("app")
)
Route组件
path
路由的路径'/'是默认路径,并且可以用通配符来表示
:paramName
,匹配URL的一个部分,直到遇到下一个/、?、#为止。这个路径参数可以通过this.props.params.paramName
取出。
()
里面的内容可选
*
匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。
**
component
路由所对应的组件。
ReactDOM.render(
<Router history = {hashHistory} >
<Route path="/" component={Hehe} />
<Route path="/index" component={index} />
</Router>,
document.getElementById("app")
)
在组件中可以写{this.props.children}
这个就是子组件,可以用作路由的嵌套。在下面势例中先加载APP
的组件,然后会根据嵌套的路径加载组件。
ReactDOM.render(
<Router history = {hashHistory} >
<Route path="/" component={APP}>
<Route path="/Hehe" component={Hehe} />
<Route path="/index" component={index} />
</Route>
</Router>,
document.getElementById("app")
)
IndexRoute
IndexRoute
作用是在路由中默认架子的一些组件放到这里
ReactDOM.render(
<Router history = {hashHistory} >
<Route path="/" component={APP}>
<IndexRoute component={indexComponent} />
{/*<IndexRedirect to={"index"} />*/}
<Route path="/Hehe" component={Hehe} />
<Route path="/index" component={index} />
</Route>
</Router>,
document.getElementById("app")
)
IndexRedirect
import {Router,Route,hashHistory,IndexRedirect} from 'react-router';
记得导入。作用是嵌套在Route
中,如果没有任何路由,制定默认的路由。
ReactDOM.render(
<Router history = {hashHistory} >
<Route path="/" component={APP}>
<IndexRedirect to={"index"} />
<Route path="/*.jpg" component={Hehe} />
<Route path="/index" component={index} />
</Route>
</Router>,
document.getElementById("app")
)
Redirect
Redirect
路由跳转,由一个路由跳转到另外一个路由有,from
当你输入哪个路由时,to
跳转到哪里去。
ReactDOM.render(
<Router history = {hashHistory} >
<Route path="/" component={APP}>
<IndexRoute component={indexComponent} />
<Redirect from="/index" to={"/indexs"} />
<Route path="/Hehe" component={Hehe}>
</Route>
<Route path="/indexs" component={index} />
</Route>
</Router>,
document.getElementById("app")
)
Link
Link
封装的组件和 a
标签的作用差不多,通过to属性来指定路由。
activeClassName
当点击这个路由时 这个属性的类样式进行生效。
activeStyle
当点击这个路由时,这个属性的内联样式生效。
class APP extends React.Component{
render(){
return <div>
"APP"
<br/>
<Link activeClassName="active" to="index">/index</Link>
<br/>
<Link activeStyle={{fontSize : "30px"}} to="Hehe">/Hehe</Link>
{this.props.children}
</div>;
}
}
IndexLink
指定根路由/
时使用
class APP extends React.Component{
render(){
return <div>
"APP"
<br/>
<IndexLink to="/" activeClassName = "active">indexLink</IndexLink>
<br/>
<Link activeClassName="active" to="index">/index</Link>
<br/>
<Link activeStyle={{fontSize : "30px"}} to="Hehe">/Hehe</Link>
{this.props.children}
</div>;
}
}
通过代码手动跳转路由
browserHistory