一、加载React:react.js 、react-dom.js 和 Browser.js
其中,react.js 是 React 的核心库,
react-dom.js 是提供与 DOM 相关的功能,
Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成
(1.1 安装Babel工具,命令如下:
npm install -g babel-cli
项目目录下安装:
npm install babel-preset-react
1.2 把test.js转换成标准的Javascript,命令如下:
babel –presets react js/src –watch –out-dir js/bin
其中:
–presets react指定编译时使用的插件
–watch表示这条命令会一直启动着,除非ctrl+c或者关闭命令提示符,作用是每次修改源文件时自动编译成目录文件
–out-dir指定编译后的js输出目录 )
PS:也可以使用CDN方法加载:
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
!!!注意:凡是使用 JSX 的地方,都要加上 type="text/babel" (即在页面引用的JS上增加,如:<script type="text/babel" src="./a.js"></script>)
二、React的基本方法:ReactDOM.render()
//页面输出Hello, world!
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
三、JSX语法:
//JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析
//如果变量是一个数组,结果 JSX 会把它的所有成员,添加到模板,展示出来
var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
<div>
{
names.map(function (name) {
return <div>Hello, {name}!</div>
})
}
</div>,
document.getElementById('example')
);
四、组件:
声明并使用组件方法1:
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="John" />,
document.getElementById('example')
);
声明并使用组件方法2:(使用ES6语法中的类,关于ES6语法参考ES6语法文档)
class HelloMessage extends React.Component {
render() {
return(
<h1>Hello {this.props.name}</h1>;
);
}
}
ReactDOM.render(
<HelloMessage name="John" />,
mountNode
);
注意:1、所有组件类都必须有自己的 render 方法,用于输出组件;
2、组件类的第一个字母必须大写;
3、组件类只能包含一个顶层标签;
4、组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取;
5、添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor
注意:关于this.props.children 与this.props与组件属性一一对应不同,this.props.children表示组件的所有子节点
this.props.children 的值有三种可能:React 提供一个工具方法 React.Children 来处理 this.props.children ,可以用 React.Children.map 来遍历子节点
1、如果当前组件没有子节点,它就是 undefined;
2、如果有一个子节点,数据类型是 object;
3、如果有多个子节点,数据类型就是 array
PropTypes:验证别人使用组件时,提供的参数是否符合要求
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired, //PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
getDefaultProps 方法可以用来设置组件属性的默认值
五、获取真实的DOM节点:
//必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点
//注意:由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错
var MyComponent = 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')
);
六、this.state:
//getInitialState 方法用于定义初始状态,这个对象可以通过 this.state 属性读取
//当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});//this.setState()可更新状态
},
render: function() {
var text = 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')
);
//PS:setState() 接受一个函数而不是一个对象,该函数将接收先前的状态作为第一个参数,将此次更新被应用时的props做为第二个参数
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
//PS:另一种定义初始化状态的方法:(使用ES6语法中的类,关于ES6语法参考ES6语法文档)
class Square extends React.Component {
constructor() {
super();//必须调用 super();方法才能在继承父类的子类中正确获取到类型的 this
this.state = {
value: null,
};
}
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
ReactDOM.render(
<Square/>,
mountNode
);
七、表单:
1)input标签:
//通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况
var Input = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function () {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>, document.body);
PS:多个输入的解决办法:
//通过给每个元素添加一个name属性,来让处理函数根据 event.target.name的值来选择做什么
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value //使用ES6当中的计算属性名语法
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
2)textarea标签:
//注意this.state.value是在构造函数中初始化,这样文本区域就能获取到其中的文本
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Please write an essay about your favorite DOM element.'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('An essay was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
3)select标签:
//在React中,并不使用之前的selected属性,而在根select标签上用value属性来表示选中项
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
4)file input标签:
八、AJAX:
最好在componentDidMount 生命周期方法内发送 AJAX 请求数据,这样才能够在请求的数据到达时使用 setState 更新组件;
可以在 React 中使用任何的 AJAX 库,例如很受欢迎的 Axios,jQuery AJAX 和浏览器内置的 window.fetch
1)AXIOS:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
//发起一个get请求,参数为给定的ID
axios.get('/user?ID=1234').then(function(respone){
console.log(response);
}).catch(function(error){
console.log(error);
});
//上面的请求也可选择下面的方式来写
axios.get('/user',{
params:{
ID:12345
}
}).then(function(response){
console.log(response);
}).catch(function(error){
console.log(error)
});
//发起一个post请求
axios.post('/user',{
firstName:'friend',
lastName:'Flintstone'
}).then(function(response){
console.log(response);
}).catch(function(error){
console.log(error);
});
2)window.fetch:
fetch('/submit-json', {
method: 'post',
body: JSON.stringify({
email: document.getElementById('email')
answer: document.getElementById('answer')
})
}).then(function(response) {
return response.text();
}).then(function(text) {
console.log(text);
});
3)JQ AJAX:
$.ajax({
url:"call/right",
type:"post",
data:{callPhone:callPhone},
dataType:"json",
success:function(data){
//成功后的回调函数
},
error:function(){
}
});
九、组件的生命周期:will 函数在进入状态之前调用,did 函数在进入状态之后调用
ounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
三种状态共计5种处理函数:
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
两种特殊状态的处理函数:
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
十、事件:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
//通常情况下,如果你没有在方法后面添加 () ,例如 onClick={this.handleClick},应该为这个方法绑定 this
//建议用以下方法在构造函数中绑定
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}> //向事件处理程序传递参数<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> e 作为 React 事件对象将会被作为第二个参数进行传递
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
其中,react.js 是 React 的核心库,
react-dom.js 是提供与 DOM 相关的功能,
Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成
(1.1 安装Babel工具,命令如下:
npm install -g babel-cli
项目目录下安装:
npm install babel-preset-react
1.2 把test.js转换成标准的Javascript,命令如下:
babel –presets react js/src –watch –out-dir js/bin
其中:
–presets react指定编译时使用的插件
–watch表示这条命令会一直启动着,除非ctrl+c或者关闭命令提示符,作用是每次修改源文件时自动编译成目录文件
–out-dir指定编译后的js输出目录 )
PS:也可以使用CDN方法加载:
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
!!!注意:凡是使用 JSX 的地方,都要加上 type="text/babel" (即在页面引用的JS上增加,如:<script type="text/babel" src="./a.js"></script>)
二、React的基本方法:ReactDOM.render()
//页面输出Hello, world!
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
三、JSX语法:
//JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析
//如果变量是一个数组,结果 JSX 会把它的所有成员,添加到模板,展示出来
var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
<div>
{
names.map(function (name) {
return <div>Hello, {name}!</div>
})
}
</div>,
document.getElementById('example')
);
四、组件:
声明并使用组件方法1:
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="John" />,
document.getElementById('example')
);
声明并使用组件方法2:(使用ES6语法中的类,关于ES6语法参考ES6语法文档)
class HelloMessage extends React.Component {
render() {
return(
<h1>Hello {this.props.name}</h1>;
);
}
}
ReactDOM.render(
<HelloMessage name="John" />,
mountNode
);
注意:1、所有组件类都必须有自己的 render 方法,用于输出组件;
2、组件类的第一个字母必须大写;
3、组件类只能包含一个顶层标签;
4、组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取;
5、添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor
注意:关于this.props.children 与this.props与组件属性一一对应不同,this.props.children表示组件的所有子节点
this.props.children 的值有三种可能:React 提供一个工具方法 React.Children 来处理 this.props.children ,可以用 React.Children.map 来遍历子节点
1、如果当前组件没有子节点,它就是 undefined;
2、如果有一个子节点,数据类型是 object;
3、如果有多个子节点,数据类型就是 array
PropTypes:验证别人使用组件时,提供的参数是否符合要求
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired, //PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
getDefaultProps 方法可以用来设置组件属性的默认值
五、获取真实的DOM节点:
//必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点
//注意:由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错
var MyComponent = 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')
);
六、this.state:
//getInitialState 方法用于定义初始状态,这个对象可以通过 this.state 属性读取
//当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});//this.setState()可更新状态
},
render: function() {
var text = 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')
);
//PS:setState() 接受一个函数而不是一个对象,该函数将接收先前的状态作为第一个参数,将此次更新被应用时的props做为第二个参数
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
//PS:另一种定义初始化状态的方法:(使用ES6语法中的类,关于ES6语法参考ES6语法文档)
class Square extends React.Component {
constructor() {
super();//必须调用 super();方法才能在继承父类的子类中正确获取到类型的 this
this.state = {
value: null,
};
}
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
ReactDOM.render(
<Square/>,
mountNode
);
七、表单:
1)input标签:
//通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况
var Input = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function () {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>, document.body);
PS:多个输入的解决办法:
//通过给每个元素添加一个name属性,来让处理函数根据 event.target.name的值来选择做什么
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value //使用ES6当中的计算属性名语法
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
2)textarea标签:
//注意this.state.value是在构造函数中初始化,这样文本区域就能获取到其中的文本
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Please write an essay about your favorite DOM element.'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('An essay was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
3)select标签:
//在React中,并不使用之前的selected属性,而在根select标签上用value属性来表示选中项
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
4)file input标签:
八、AJAX:
最好在componentDidMount 生命周期方法内发送 AJAX 请求数据,这样才能够在请求的数据到达时使用 setState 更新组件;
可以在 React 中使用任何的 AJAX 库,例如很受欢迎的 Axios,jQuery AJAX 和浏览器内置的 window.fetch
1)AXIOS:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
//发起一个get请求,参数为给定的ID
axios.get('/user?ID=1234').then(function(respone){
console.log(response);
}).catch(function(error){
console.log(error);
});
//上面的请求也可选择下面的方式来写
axios.get('/user',{
params:{
ID:12345
}
}).then(function(response){
console.log(response);
}).catch(function(error){
console.log(error)
});
//发起一个post请求
axios.post('/user',{
firstName:'friend',
lastName:'Flintstone'
}).then(function(response){
console.log(response);
}).catch(function(error){
console.log(error);
});
2)window.fetch:
fetch('/submit-json', {
method: 'post',
body: JSON.stringify({
email: document.getElementById('email')
answer: document.getElementById('answer')
})
}).then(function(response) {
return response.text();
}).then(function(text) {
console.log(text);
});
3)JQ AJAX:
$.ajax({
url:"call/right",
type:"post",
data:{callPhone:callPhone},
dataType:"json",
success:function(data){
//成功后的回调函数
},
error:function(){
}
});
九、组件的生命周期:will 函数在进入状态之前调用,did 函数在进入状态之后调用
ounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
三种状态共计5种处理函数:
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
两种特殊状态的处理函数:
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
十、事件:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
//通常情况下,如果你没有在方法后面添加 () ,例如 onClick={this.handleClick},应该为这个方法绑定 this
//建议用以下方法在构造函数中绑定
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}> //向事件处理程序传递参数<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> e 作为 React 事件对象将会被作为第二个参数进行传递
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);