[深入剖析React Native]React 初探
认识React
React特点
基础知识在学习React之前,需要具备一下基础知识: 简单实例<div id="example"></div>
<script type="text/babel"> ReactDOM.render( <h1>Hello World!</h1> document.getElementById('example') ); </script>
React安装使用库:<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
使用实例: <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel"> ReactDOM.render( <h1>Hello,world!</h1>,document.getElementById('example') ); </script>
</body>
</html>
实例解析: ReactDOM.render(
<h1>Hello,document.getElementById('example')
);
以上代码将一个 h1 标题,插入 id=”example” 节点中。
通过npm使用React我们建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack,本教程使用 webpack。 安装全局包$ npm install babel -g
$ npm install webpack -g
$ npm install webpack-dev-server -g
创建根目录创建一个根目录,名称为mazouriApp,再使用npm init初始化,生成package.json文件: 添加依赖包及插件因为我们要使用React,所以我们需要先安装它, –save命令用于将包添加至package.json文件 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
创建文件接下来我们创建一些必要的文件: touch index.html
touch App.jsx
touch main.js
touch webpack.config.js
设置编译器、服务器、载入器打开webpack.config.js 文件添加以下代码: var config = {
entry: './main.js',outout: {
path: './',filename: 'index.js',},devServer: {
inline: true,port: 7777
},module: {
loaders: [{
test: /.jsx?$/,exclude: /node_moudules/,loader: 'babel-loader',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 文件 内容如下: {
"name": "mazouri-react-demo","version": "1.0.0","description": "我的react demo","main": "index.js","scripts": { "start": "webpack-dev-server --hot" },"author": "","license": "ISC","dependencies": { "react": "^15.3.1","react-dom": "^15.3.1" } }
现在我们可以使用 npm start 命令来启动服务。–hot 命令会在文件变化后重新载入,这样我们就不需要在代码修改后重新刷新浏览器就能看到变化。 index.html设置 div id = “app” 为我们应用的根元素,并引入 index.js 脚本文件 <!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>mazouri React demo</title>
</head>
<body>
<div id = "app"></div>
<script src = "index.js"></script>
</body>
</html>
App.jsx 和 main.js这是第一个 react 组件,这个组件将输出 Hello World!!!。 import React from 'react';
class App extends React.Component {
render() {
return (
<div>
Hello World!!!<br />
这是mazouri react app的一个demo
</div>
);
}
}
export default App;
我们需要引入组件并将其渲染到根元素 App 上,这样我们才可以在浏览器上看到它 import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />,document.getElementById('app'))
运行服务完成以上配置后,我们即可运行该服务: $ npm start
JSXReact 使用JSX来代替常规的JavaScript。
使用JSXJSX看起来类似HTML,我们可以看下实例: ReactDOM.render(
<h1>Hello,document.getElementById('example')
);
我们可以在上面代码中嵌套多个HTML标签,需要使用一个div元素包裹它,实例中的p元素添加了自定义属性data-myattribute,添加自定义属性需要使用data-前缀。 ReactDOM.render(
<div>
<h1>标题</h1>
<h2>React初探</h2>
<p data-myattribute = "somevalue">这是一个段落</p>
</div>,document.getElementById('example')
);
独立文件你的React JSX 代码可以放在一个独立文件上,例如我们创建一个helloworld_react.js文件,代码如下: ReactDOM.render(
<h1>Hello,document.getElementById('example')
);
然后在 HTML 文件中引入该 JS 文件: <body>
<div id="example"></div>
<script type="text/babel" src="helloworld_react.js"></script>
</body>
JavaScript 表达式我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下: ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div>,document.getElementById('example')
);
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true,如果修改 i 的值,则会输出 false. ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>,document.getElementById('example')
);
样式React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式: var myStyle = {
fontSize: 100,color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>菜鸟教程</h1>,document.getElementById('example')
);
注释注释需要写在花括号中,实例如下: ReactDOM.render(
<div>
<h1>React初探</h1>
{/*注释...*/}
</div>,document.getElementById('example')
);
数组JSX 允许在模板中插入数组,数组会自动展开所有成员: var arr = [
<h1>React初探</h1>,<h2>学习React技术!</h2>,];
ReactDOM.render(
<div>{arr}</div>,document.getElementById('example')
);
HTML 标签 vs. React 组件React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。 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'));
React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
React 组件这节我们讨论如何使用组件使得我们的应用更容易来管理。 var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!</h1>;
}
});
ReactDOM.render(
<HelloMessage />,document.getElementById('example')
);
实例解析:
如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下: var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Runoob" />,document.getElementById('example')
);
以上实例中 name 属性通过 this.props.name 来获取. 注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
复合组件我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。 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="Geek马走日" site="https://github.com/mazouri" />,document.getElementById('example')
);
实例中 WebSite 组件使用了 Name 和 Link 组件来输出对应的信息,也就是说 WebSite 拥有 Name 和 Link 的实例 React State(状态)React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。 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>
);
}
});
React.render(
<LikeButton />,document.getElementById('example')
);
React Propsstate 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据 使用 Props以下实例演示了如何在组件中使用 props: var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Runoob" />,document.getElementById('example')
);
实例中 name 属性通过 this.props.name 来获取。 默认 Props你可以通过 getDefaultProps() 方法为 props 设置默认值,实例如下: var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'Runoob'
};
},render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage />,document.getElementById('example')
);
State 和 Props以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中,我们设置 name 和 site 来获取父组件传递过来的数据 var WebSite = React.createClass({
getInitialState: function() {
return {
name: "Geek马走日",site: "https://github.com/mazouri"
};
},render: function() {
return (
<div>
<Name name={this.state.name} />
<Link site={this.state.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 />,document.getElementById('example')
);
Props 验证Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。 var title = "React 初探";
// var title = 123;
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle title={title} />,document.getElementById('example')
);
更多验证器说明如下: 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!');
}
}
},/* ... */
});
React 组件 API这节我们将讨论 React 组件 API。我们将讲解以下7个方法:
设置状态:setStatesetState(object nextState[,function callback])
参数说明 关于setState不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换 实例var Counter = React.createClass({
getInitialState: function () {
return { clickCount: 0 };
},handleClick: function () {
this.setState(function(state) {
return {clickCount: state.clickCount + 1};
});
},render: function () {
return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>);
}
});
ReactDOM.render(
<Counter />,document.getElementById('message')
);
实例中通过点击 h2 标签来使得点击计数器加 1 替换状态:replaceStatereplaceState(object nextState[,function callback])
设置属性:setPropssetProps(object nextProps[,function callback])
替换属性:replacePropsreplaceProps(object nextProps[,function callback])
强制更新:forceUpdateforceUpdate([function callback])
获取DOM节点:findDOMNodeDOMElement findDOMNode()
判断组件挂载状态:isMountedbool isMounted()
React组件生命周期组件的生命周期可以分为三个状态: var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
},componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1) {
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this),100);
},render: function () {
return (
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
</div>
);
}
});
ReactDOM.render(
<Hello name="world"/>,document.body
);
以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中 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() {
console.log('Component WILL MOUNT!')
},componentDidMount:function() {
console.log('Component DID MOUNT!')
},componentWillReceiveProps:function(newProps) {
console.log('Component WILL RECIEVE PROPS!')
},shouldComponentUpdate:function(newProps,newState) {
return true;
},componentWillUpdate:function(nextProps,nextState) {
console.log('Component WILL UPDATE!');
},componentDidUpdate:function(prevProps,prevState) {
console.log('Component DID UPDATE!')
},componentWillUnmount:function() {
console.log('Component WILL UNMOUNT!')
},render: function () {
return (
<div>
<h3>{this.props.myNumber}</h3>
</div>
);
}
});
ReactDOM.render(
<div>
<Button />
</div>,document.getElementById('example')
);
React AJAXReact 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI. 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" />,mountNode
);
以上代码使用 jQuery 完成 Ajax 请求。 React 表单与事件一个简单实例在实例中我们设置了输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state。我们可以使用 onChange 事件来监听 input 的变化,并修改 state var HelloMessage = React.createClass({
getInitialState: function() {
return {value: 'Hello Runoob!'};
},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} />
<h4>{value}</h4>
</div>;
}
});
ReactDOM.render(
<HelloMessage />,document.getElementById('example')
);
上面的代码将渲染出一个值为 Hello Runoob! 的 input 元素,并通过 onChange 事件响应更新用户输入的值 实例 2在以下实例中我么将为大家演示如何在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。 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 Runoob!'};
},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')
);
React 事件以下实例演示通过 onClick 事件来修改数据: var HelloMessage = React.createClass({
getInitialState: function() {
return {value: 'Hello Runoob!'};
},handleChange: function(event) {
this.setState({value: '菜鸟教程'})
},render: function() {
var value = this.state.value;
return <div>
<button onClick={this.handleChange}>点我</button>
<h4>{value}</h4>
</div>;
}
});
ReactDOM.render(
<HelloMessage />,document.getElementById('example')
);
当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下: var Content = React.createClass({
render: function() {
return <div>
<button onClick = {this.props.updateStateProp}>点我</button>
<h4>{this.props.myDataProp}</h4>
</div>
}
});
var HelloMessage = React.createClass({
getInitialState: function() {
return {value: 'Hello Runoob!'};
},document.getElementById('example')
);
React RefsReact 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。 使用方法绑定一个 ref 属性到 render 的返回值上: <input ref="myInput" />
在其它代码中,通过 this.refs 获取支撑实例: var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
完整实例你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下: 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')
);
实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。 转载请标注地址:Geek马走日 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |