Reactjs入门
阮一峰网络日志:http://www.ruanyifeng.com/blog/2015/03/react.html
React学习文档:http://reactjs.cn/react/docs/getting-started.html
1、jsx
-- 在javascript代码里写着xml格式的代码叫做jsx
-- javascript语法扩展,react用来做简单的句法转换
-- jsx能定义简介且包含属性的树状结构语法
-- react jsx代码文件可以写在单独的文件里
2、props与state
props属性
-- 组件的属性可以通过this.props对象上获取, 且是一一对应关系
-- 由于class 和for是js的保留字,故添加组件属性时需要注意,属性名分别为写className、htmlFor
-- this.props.children表示组件上的所有子节点,其值有三种情况:
没有子节点,为undefined;
一个子节点,数据类型为object类型;
多个子节点,数据类型为array类型
-- React.Children方法来处理this.props.children,使用React.Children.map()遍历子节点,而不用担心子节点是undefined还是object类型
-- PropsType用于验证组件实例的属性是否符合要求
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
state
组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI. 查看demo8: https://github.com/ruanyf/react-demos/blob/master/demo08/index.html
varLikeButton=React.createClass({
getInitialState:function(){
return{liked:false};
},
handleClick:function(event){
this.setState({liked:!this.state.liked});
},
render:function(){
vartext=this.state.liked?'like':'haven\'t liked';
return(
<p onClick={this.handleClick}>
You{text}this.Click to toggle.
</p>
);
}
});
ReactDOM.render(
<LikeButton/>,
document.getElementById('example')
);
上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件
props与state
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性.
--getDefaultProps用于定义属性,不可变化
--getInitialState用于定义初始状态,可变化
--用户在表单填写信息,属于用户跟组件的互动,不能用this.props获取
3、组件定义使用规则
组件并不是真实的dom节点,而是存在于内存之中的一种真实的数据结构,只有插入文档之后才会变成真实的dom。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff.(值à状态à页面):可以极大的提高网页性能
-- React.createClass()方法用于生成组件类
-- 所有组件类必须有自己的render()方法,用于输出组件
-- 所有组件类首字母必须大写,否则会报错
-- 组件类只能包含一个顶层标签,否则也会报错
-- React组件支持的事件有onClick、onKeyDown、onCopy、onCut、onPaste、onScroll、onChange等,更多事件官方文档:https://facebook.github.io/react/docs/events.html#supported-events
4、ref属性
组件上获取真实的DOM节点,通过ref获取:
varMyComponent=React.createClass({
handleClick:function(){
this.refs.myTextInput.focus();
},
render:function(){
return(
<div>
<input type="text"ref="myTextInput"/>
<input type="button"value="Focus the text input"onClick={this.handleClick}/>
</div>
);
}
});
ReactDOM.render(
<MyComponent/>,
document.getElementById('example')
);
必须等到虚拟DOM插入到文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。
5、表单
varInput=React.createClass({
getInitialState:function(){
return{value:'Hello!'};
},
handleChange:function(event){
this.setState({value:event.target.value});
},
render:function(){
varvalue=this.state.value;
return(
<div>
<input type="text"value={value}onChange={this.handleChange}/>
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>,document.body);
上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况,更多参与官方文档:
6、组件的生命周期
组件的生命周期分为三种状态:
Mounting:已插入真实 DOM -- componentDidMount
Updating:正在被重新渲染 -- componentWillUpdate
Unmounting:已移出真实 DOM
React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数
- componentWillMount()
- componentDidMount()
- componentWillUpdate(object nextProps, object nextState)
- componentDidUpdate(object prevProps, object prevState)
- componentWillUnmount()
此外,React 还提供两种特殊状态的处理函数。
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
7、ajax
组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI
varUserGist=React.createClass({
getInitialState:function(){
return{
username:'',
lastGistUrl:''
};
},
componentDidMount:function(){
$.get(this.props.source,function(result){
varlastGist=result[0];
if(this.isMounted()){
this.setState({
username:lastGist.owner.login,
lastGistUrl:lastGist.html_url
});
}
}.bind(this));
},
render:function(){
return(
<div>
{this.state.username}'s last gist is
<a href={this.state.lastGistUrl}>here</a>.
</div>
);
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists"/>,
document.body
);
上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。我们甚至可以把一个Promise对象传入组件
ReactDOM.render(
<RepoList
promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')}
/>,
document.body
);
上面代码从Github的API抓取数据,然后将Promise对象作为属性,传给RepoList组件.
如果Promise对象正在抓取数据(pending状态),组件显示"正在加载";如果Promise对象报错(rejected状态),组件显示报错信息;如果Promise对象抓取数据成功(fulfilled状态),组件显示获取的数据。
varRepoList=React.createClass({
getInitialState:function(){
return{loading:true,error:null,data:null};
},
componentDidMount(){
this.props.promise.then(
value=>this.setState({loading:false,data:value}),
error=>this.setState({loading:false,error:error}));
},
render:function(){
if(this.state.loading){
return<span>Loading...</span>;
}
elseif(this.state.error!==null){
return<span>Error:{this.state.error.message}</span>;
}
else{
varrepos=this.state.data.items;
varrepoList=repos.map(function(repo){
return(
<li>
<a href={repo.html_url}>{repo.name}</a>({repo.stargazers_count}stars)<br/>{repo.description}
</li>
);
});
return(
<main>
<h1>Most Popular JavaScript ProjectsinGithub</h1>
<ol>{repoList}</ol>
</main>
);
}
}
});
8、采用react+node实现同构及组件化
-- React.js相当于MVC框架的视图层
-- isomorphic (同构) : 同时在客户端和服务器端渲染页面
-- 同构js通常是同构node.js和io.js实现
-- react.js就是一种支持同构的框架

浙公网安备 33010602011771号