1、React 安装
通过 npm 使用 React
(1)安装全局包
$ npm install babel -g
$ npm install webpack -g
$ npm install webpack-dev-server -g
(2)创建根目录
目录名 --> reactApp --> npm init 初始化 --> 生成 package.json:
$ mkdir reactApp
$ cd reactApp/
$ npm init
name: (reactApp) youj-react-test
version: (1.0.0)
description: W3Cschool教程 react 测试
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/laolan/www/reactApp/package.json:
{
"name": "youj-react-test",
"version": "1.0.0",
"description": "W3Cschool教程 react 测试",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes)
(3)添加依赖包及插件
$ npm install react --save
$ npm install react-dom --save
babel
插件
$ npm install babel-core
$ npm install babel-loader
$ npm install babel-preset-react
$ npm install babel-preset-es2015
(4)创建文件
$ touch index.html
$ touch App.jsx
$ touch main.js
$ touch webpack.config.js
(5)设置编译器,服务器,载入器
webpack.config.js
var config = {
entry: './main.js', //指定打包的入口文件
output: { // 配置打包结果
path:'./', // 输出的文件夹
filename: 'index.js', // 打包结果文件的名称
},
devServer: { // 设置服务器端口号
inline: true,
port: 7777
},
module: { // 对模块的处理逻辑
loaders: [ {
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}]
}
}
module.exports = config;
打开 package.json
文件,找到 “scripts
” 中的 “test
” “echo \"Error: no test specified\" && exit 1
”
使用以下代码替换:
"start": "webpack-dev-server --hot"
替换后的 package.json
:
$ cat package.json
{
"name": "youj-react-test",
"version": "1.0.0",
"description": "W3Cschool教程 react 测试",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --hot" // --hot 命令会在文件变化后重新载入
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^0.14.7",
"react-dom": "^0.14.7"
}
}
(6)index.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>React</title>
</head>
<body>
<div id = "app"></div>
<script src = "index.js"></script>
</body>
</html>
(7)App.jsx 和 main.js
App.jsx
import React from 'react';
class App extends React.Component {
render() {
return (
<div>
Hello World!!!<br />
欢迎来到W3Cschool教程学习!!!
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />, document.getElementById('app'))
(8)运行服务
$ npm start
2、React JSX
1、在 JSX 中 JavaScript 表达式写在花括号 {} 中。
2、JSX 中不能使用 if else 语句,可使用 conditional (三元运算) 。
3、可使用 camelCase 语法来设置内联样式。
4、注释需写在花括号中。
5、JSX 允许在模板中插入数组并会自动展开所有成员。
6、React 渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名;渲染 React 组件,只需创建一个大写字母开头的本地变量。
7、由于 JSX 就是 -,一些标识符像 class
和 for
不建议作为 XML 属性名。作为替代,React DOM 使用 className
和 htmlFor
来做对应的属性。
var myStyle = {
fontSize : 30,
color : "#FF0000"
};
var arr = [
<h1>我是老大</h1>,
<h2>我是老二</h2>,
];
ReactDOM.render(
<div>
<h1 style = {myStyle}>{i = 1 ? 'True!' : 'False'}</h1>
{/*注释...*/}
<div>{arr}</div>
</div>,
document.getElementById('example')
);
// 渲染HTML
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
// 渲染 React 组件
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));
3、React 组件
1、原生 HTML 元素名以小写字母开头,自定义的 React 类名以大写字母开头。
2、组件类只能包含一个顶层标签,否则也会报错。
3、组件传参 --> this.props
对象。
var WebSite = React.createClass({
render: function() {
return (
<div>
<Name name={this.props.name} />
<Link site={this.props.site} />
</div>
);
}
});
var Name = React.createClass({
render: function() {
return (
<h1>{this.props.name}</h1>
);
}
});
var Link = React.createClass({
render: function() {
return (
<a href={this.props.site}>
{this.props.site}
</a>
);
}
});
React.render(
<WebSite name="W3Cschool教程" site=" https://www.w3cschool.cn" />,
document.getElementById('example')
);
4、React State(状态)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>react state</title>
<script src="//www.w3cschool.cn/statics/assets/react/react.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/react-dom.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/babel.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
var LikeButton = React.createClass({
// 初始状态
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? '喜欢' : '不喜欢';
return (
<p onClick={this.handleClick}>
<b>{text}</b>...点我切换状态。
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
</script>
</body>
</html>
5、React Props(属性)
1、state
--> 可变,props
--> 不可变。
2、getDefaultProps()
--> props 设置默认值。
3、React.PropTypes
--> props验证。
var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'React'
};
},
render: function() {
return <h1>Hi {this.props.name}</h1>;
}
});
React.createClass({
propTypes: {
// 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
// 可以被渲染的对象 numbers, strings, elements 或 array
optionalNode: React.PropTypes.node,
// React 元素
optionalElement: React.PropTypes.element,
// 用 JS 的 instanceof 操作符声明 prop 为类的实例。
optionalMessage: React.PropTypes.instanceOf(Message),
// 用 enum 来限制 prop 只接受指定的值。
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// 可以是多个对象类型中的一个
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
]),
// 指定类型组成的数组
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
// 指定类型的属性构成的对象
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
// 特定 shape 参数的对象
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// 任意类型加上 `isRequired` 来使 prop 不可空。
requiredFunc: React.PropTypes.func.isRequired,
// 不可空的任意类型
requiredAny: React.PropTypes.any.isRequired,
// 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
},
/* ... */
});
6、React 组件 API
1、setState
--> 设置状态
setState(object nextState[, function callback])
// nextState --> 新状态,和当前的state合并
// callback --> 在setState设置成功,且组件重新渲染后调用。
// 示例:
handleClick: function () {
this.setState(function(state) {
return {clickCount: state.clickCount + 1};
});
},
2、replaceState
--> 替换状态
replaceState(object nextState[, function callback])
// replaceState()与setState()类似,
// replaceState()只保留nextState中状态,
// 原state不在nextState中的状态都会被删除。
3、setProps
--> 设置属性
setProps(object nextProps[, function callback])
4、replaceProps
--> 替换属性
replaceProps(object nextProps[, function callback])
5、forceUpdate
--> 强制更新
forceUpdate([function callback])
// 尽量避免使用forceUpdate()
6、findDOMNode
--> 获取DOM节点
DOMElement findDOMNode()
// 返回值:DOM元素DOMElement
7、isMounted
--> 判断组件挂载状态
bool isMounted()
// 返回值:true或false,表示组件是否已挂载到DOM中
7、React 组件生命周期
1、又叫钩子函数,响应不同的状态。
2、组件的生命周期可分成三个状态:
Mounting
--> 已插入真实 DOM
Updating
--> 正在被重新渲染
Unmounting
--> 已移出真实 DOM
3、
var Button = React.createClass({
getInitialState: function() {
return {
data:0
};
},
setNewNumber: function() {
this.setState({data: this.state.data + 1})
},
render: function () {
return (
<div>
<button onClick = {this.setNewNumber}>INCREMENT</button>
<Content myNumber = {this.state.data}></Content>
</div>
);
}
})
var Content = React.createClass({
componentWillMount:function() {
// 渲染前调用
},
componentDidMount:function() {
// 第一次渲染后调用
// 可在该方法中调用setTimeout, setInterval或发送AJAX请求等操作
},
componentWillReceiveProps:function(newProps) {
// 组件接收到一个新的prop时被调用,初始化render时不被调用
},
shouldComponentUpdate:function(newProps, newState) {
// 返回一个布尔值。组件接收到新的props或state时被调用。初始化时或使用forceUpdate时不被调用。
return true;
},
componentWillUpdate:function(nextProps, nextState) {
// 组件接收到新的props或state但还没有render时被调用。初始化时不被调用。
},
componentDidUpdate:function(prevProps, prevState) {
// 组件完成更新后立即调用,初始化时不被调用。
},
componentWillUnmount:function() {
// 组件从 DOM 中移除的时候立刻被调用。
},
render: function () {
return (
<div>
<h3>{this.props.myNumber}</h3>
</div>
);
}
});
ReactDOM.render(
<div>
<Button />
</div>,
document.getElementById('example')
);
8、React AJAX
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>W3Cschool教程 React 实例</title>
<script src="//www.w3cschool.cn/statics/assets/react/react.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/react-dom.min.js"></script>
<script src="//www.w3cschool.cn/statics/assets/react/babel.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function (result) {
var lastGist = result[0];
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
{this.state.username} 用户最新的 Gist 共享地址:
<a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
</div>
);
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists" />,
document.getElementById('example')
);
</script>
</body>
</html>
9、React 表单与事件
var Content = React.createClass({
render: function() {
return <div>
<input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} />
<h4>{this.props.myDataProp}</h4>
</div>;
}
});
var HelloMessage = React.createClass({
getInitialState: function() {
return {value: 'Hello W3CSchool!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <div>
<Content myDataProp = {value}
updateStateProp = {this.handleChange}></Content>
</div>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
10、React Refs
var MyComponent = React.createClass({
handleClick: function() {
// 使用原生的 DOM API 获取焦点
this.refs.myInput.focus();
},
render: function() {
// 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
return (
<div>
<input type="text" ref="myInput" />
<input
type="button"
value="点我输入框获取焦点"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);