渲染React组件
通过ReactDOM直接渲染
ReactDOM.render(
<span>Hello World!</span>,
document.getElementById('example')
);
通过React.Component创建组件再通过ReactDOM渲染(推荐方法)
class MyTitle extends React.Component {
render() {
return <h1>Hello World</h1>;
}
};/*该段表示MyTitle类继承基类React.Component下所有属性及方法*/
ReactDOM.render(
<MyTitle/>,
document.getElementById('example')
);
通过React.createClass创建组件再通过ReactDOM渲染
const MyTitle = React.createClass({
render () {
return return <h1>Hello World</h1>;
}
})/*从 React 0.13 开始,官方推荐使用 ES6 类语法来进行组件的定义*/
关于React组件中的数据传递
通过this.props传参获取数据,React还提供一个refs方式用来获取真实的DOM结点
/*this.props*/
class MyTitle extends React.Component {
render() {
return <h1 style={{color: this.props.color}}>Hello World</h1>;
}
};
ReactDOM.render(
<MyTitle color="red" />,
document.getElementById('example')
);
/*this.refs*/
var MyTitle = 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(
<MyTitle />,
document.getElementById('example')
);
每个组件都有她自身的内部状态,这边是this.state,React在ES6的实现中去掉了getInitialState这个hook函数,规定state在constructor中实现
class MyTitle extends React.Component {
constructor(...args) {/*组件构造函数*/
super(...args);
this.state = {
name: '访问者'/*定义初始状态*/
};
}/*定义一个组件*/
handleChange(e) {
let name = e.target.value;
this.setState({
name: name
});
}
render() {
return <div>{/*.bind(this)表示该方法内部的this绑定当前组件*/}
<input type="text" onChange={this.handleChange.bind(this)} />
{/*当onChange时调用handleChange事件重新渲染组件*/}
<p>你好,{this.state.name}</p>
</div>;
}
};
ReactDOM.render(
<MyTitle/>,
document.getElementById('example')
);
React本身为组件不同的生命阶段提供了不同的钩子方法(钩子方法简单来说就是一些运行在特定的某一状态前后的方法),可以利用这些方法
componentWillMount() /*组件加载前*/
componentDidMount() /*组件加载后(一般在此时发出Ajax请求)*/
componentWillUpdate() /*组件更新前*/
componentDidUpdate() /*组件更新后*/
componentWillUnmount() /*组件卸载前*/
componentWillReceiveProps() /*组件接受新的参数时*/
最后是Ajax请求,React组件中的Ajax请求一般在组件生命周期中的componentDidMount发出
class MyList extends React.Component {
constructor(...args) {
super(...args);
this.state = {
loading: true, /*设置初始state*/
error: null,
data: null
};
}
componentDidMount() {
const url = 'https://api.github.com/search/repositories?q=javascript&sort=stars';/*调用api*/
$.getJSON(url)
.done(
(value) => this.setState({
loading: false,
data: value/*把获取的数据value装载到data中*/
})
).fail(
(jqXHR, textStatus) => this.setState({
loading: false,
error: jqXHR.status/*一旦失败的话就装载error*/
})
);
}
render() {
if (this.state.loading) {
return <span>Loading...</span>;
} else if (this.state.error !== null) {
return <span>Error: {this.state.error}</span>;
} else {
console.log(this.state.data);/*先输出到控制台查看数据结构*/
/*处理数据*/
var projects = this.state.data.items;
var results = [];
projects.forEach(p => {
var item = <li>{p.name}</li>;
results.push(item);
});
return (
<div>
<p>API 数据获取成功</p>
<ul>{results}</ul>
</div>
);
}
}
};
ReactDOM.render(
<MyList/>,
document.getElementById('example')
);
关于React组件的嵌套
React组件的思想很简单,就是用一个组件装载其他组件,这便是组件的嵌套
/*装载组件*/
var Avatar =React.createClass({
render: function() {
return (
<div>
<ProfilePicusername={this.props.username} />
<ProfileLinkusername={this.props.username} />
</div>
);
}
});
/*子组件*/
var ProfilePic =React.createClass({
render: function() {
return (
<img src={'http://graph.facebook.com/'+ this.props.username + '/picture'} />
);
}
});
var ProfileLink =React.createClass({
render: function() {
return (
<a href={'http://www.facebook.com/' +this.props.username}>
{this.props.username}
</a>
);
}
});
/*渲染装载组件*/
React.render(
<Avatar username="pwh" />,
document.getElementById('example')
);
高阶组件
高阶组件就是返回组件的组件,她可以在不修改原组件的前提下,修改或增强原组件的行为
function noId() {
return function(Comp) { /*返回一个接收组件的函数*/
return class NoID extends Component { /*该函数返回一个组件*/
render() {
const {id, ...others} = this.props
return (
<Comp {..others} />
)
}
}
}
}
const WithoutID = noId()(Comp)
propTypes
用于检查组件的数据类型是否准确
MyElysion.propTypes ={
El: PropTypes.string.isRequired,
Elys: PropTypes.array.isRequired,
Elysion: PropTypes.func.isRequired
}
未完待续