what is react
- 构建用户界面的javascript库(非框架), 轻量级
- 构建UI, mvc中v
- 虚拟dom, 提升页面渲染速度, 变化部分局部更新
- jsx模板语言, 具有javascript全部功能, 是js扩展(非引入新概念指令、控制器)
- 组件化, 增强代码复用、组件独立测试
- 单向数据流, 比数据绑定更简单(非双向绑定:数据来源混乱)
相关:
- http://www.runoob.com/react/react-tutorial.html
- https://facebook.github.io/react/docs/installation.html
- http://www.ruanyifeng.com/blog/2015/03/react.html
ReactDOM.render()
模板转化html语言, 插入指定的dom
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
React JSX
- Babel编译jsx->React.createElement(),不使用jsx也可以全通过js React,但是代码不简洁, 意思上是等价
react元素创建,两种方式等价-->元素区别组件
const getHelloWord = <h1>Hello, world!</h1>
const element = React.createElement(
'h1',
'Hello, world!'
);
- 遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析
- 渲染之前,转义jsx值, 避免xss攻击
- javaScript表达式: jsx中使用js表达式, 包裹{}
function formatName(user) { return user.firstName + ' ' + user.lastName; } function getGreeting(user) { return <h1>Hello, {formatName(user)}</h1>;-->{} } - jsx[用html元素]行内不能使用if、if else 语句
if: &代替 const getGreeting(isOpen) = <div>{isOpen && true}</div>if else:-->三元运算代替 const getGreeting(isOpen) = <div>{isOpen ? true : false}</div> - 内联样式
const myStyle = { fontSize: 100,--->元素数字后自动添加px, 驼峰转化 color: '#FF0000' }; const getGreeting() { return <div style={myStyle}></div>} - 数组元素->数组所有成员添加模板中
const arr = [<h1>arr1</h1>, <h2>arr2</h2>] const getGreeting() { return <div>{arr}</div>}
React 组件
- react元素 vs 组件命名:
- 元素以小写字母开头, 组件以大写字母开头
- 元素引用直接 元素名(所以无法传递props), 组件<element props
- 元素创建的3中方式
- 函数方式
- es6 class
- React.createClass
function HelloWord(props) {-->props传递 <div>{props.name}</div> }class HelloWolrd extends React.Component { render(){ return <div>{this.props.name}</div> } }var HelloWolrd = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } });调用: ```
```
React props
- this.props.children: 表示组件的所有子节点
- 没有子节点undefined
- 有一个子节点,数据类型是 object
- 有多个子节点,数据类型就是 array
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;-->React.Children获取所有子节点, React.Children.map遍历子节点
})
React state
- 就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI
- state vs props
- props不再改变的特性,而this.state 是会随着用户互动而产生变化的特性
- props父组件传递, state组件内部状态
- this.state属性读取, this.setState({})变更state
handleClick() { this.setState({'isOpen': !this.state.isOpen}) } class Hello extends react.Component{ render(){ const isOpen = this.state.isOpen; return <a onClick=this.handleClick()>{isOpen ? true: false}</> } }
列表遍历、和列表key(类似js map)
List元素:
const listItems = numbers.map((number, index) =>
<li>{number}</li>
);
List组件:html标签外
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number, index) =>
<li key={唯一的标记, 非遍历中的index索引}>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
List组件:html内标签外, {}包裹, 两种方式等价
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<li>{number}</li>
)}
</ul>
);
}
- 遍历添加key: 唯一标记这条记录,虚拟dom比较索引,加载查找速度
- 不要使用map->index作为key
- 不用组件中, 定义相关的key, 无影响
- NumberList->ListItem->li多层组件, key添加到ListItem非遍历li上
- key不存在props传递中, 如果需要传递唯一标识,可以id替换
Forms
react form elements例如input、textarea、select跟html中区别
- html: 用户输入界面, 界面值变更。
- react: 需要onChange事件的回调函数,通过 event.target.value 读取用户输入的值,设置setState() 界面值变更
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> ); }
组件组合和继承
建议组合增强复用性, 非继承
继承三种方式
- 对子节点类型不明确–>只有一个子组件props.children
function FancyBorder(props) {
return (
<div>
{props.children}
</div>
);
}
调用:
<FancyBorder>
<div></div>--->这个位置除了普通元素, 也可以是组件
<FancyBorder>
- 多个子组件类型不明确–>两个props
function FancyBorder(props) {
return (
<div>
{props.left}
</div>
<div>
{props.right}
</div>
);
}
调用:
<FancyBorder>
left={<A />}
right={<B />}--->这个位置除了普通元素, 也可以是组件
<FancyBorder>
- A组件是B组件一个特例
function Dialog(props) {
return (
<FancyBorder>
<h1>
{props.title}
</h1>
<p>
{props.message}
</p>
</FancyBorder>
);
}
function WelcomeDialog() {
return (
<Dialog
title="Welcome"
message="test" />
);
}