JSX Javascript + XML
React 不强制要求使用 JSX,但是大多数人发现,在 JavaScript 代码中将 JSX 和 UI 放在一起时,会在视觉上有辅助作用
<h1>Hello, {name}</h1> // {variable}
在编译之后,JSX 表达式会被转为普通 JavaScript 函数调用,并且对其取值后得到 JavaScript 对象
可使用if/else等表达式
JSX更接近JS,而不是HTML,onClick, onChange, tabIndex等驼峰命名法
JSX避免XSS攻击
Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React DOM
React DOM并不是浏览器的DOM
根DOM节点,该节点内的所有内容都将由 React DOM 管理 React DOM是不可更改的对象,一旦创建不可更改,只能调用Render方法重新创建 只改变需要更新的DOM元素,轻量Components & Props
定义组件的两种方式:
// Js function:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// ES6 Class
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
通过JSX定义组件,会将组件接收的属性和组件的children转换为单个对象props props是只读属性
States & 生命周期
states与props类似,私有,且完全受控于当前组件, state是组件内部用来处理各种变化的对象,props是父传子用的对象
- 不能直接修改state,使用setState方法
- 构造函数是唯一可以给this.stste初始复制的地方
- 多个setState可能会被合并调用导致state和props异步更新问题,两者有依赖时使用箭头函数
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
- setState会将多次操作合并
- States只能在组件内部访问,外部无法获取其状态
- 可将state作为props传入子组件,“自上而下”或是“单向”的数据流
- componentDidMount(挂载) componentWillUnmount(卸载)
事件处理
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
onClick={functionName}onClick={this.handleClick} & this.handleClick = this.handleClick.bind(this);通常情况下,如果你没有在方法后面添加 (),例如onClick={this.handleClick},你应该为这个方法绑定this,或者使用箭头函数 - 也可在回调中使用箭头函数
<button onClick={() => this.handleClick()}>Click me</button>
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button> // 隐式传递e
条件渲染
React支持使用 JavaScript 运算符 if 或者条件运算符去创建DOM元素
function Greetings(props){
const isLoggedIn = props.isLoggedIn;
if(isLoggedIn){
return <UserGreeting/>;
}
return <GuestGreeting/>
}
if(isLoggedIn){
btn = <LogoutBtn onClick={this.handleLogoutClick} />
} else {
btn = <LoginBtn onClick={this.handleLoginClick} />
}
<div>{btn}</div>
与运算符 &
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
三目运算:
<div>The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.</div>
阻止组件渲染(render 方法直接返回 null) - 在组件的 render 方法中返回 null 并不会影响组件的生命周期,componentDidUpdate仍会被调用
列表 & Key
可以使用{}在JSX中构建元素集合,注意要给列表元素分配一个 key 属性,否则会有警告
render () {
const list = [1,2,3,4,5];
const items = list.map(item =>
<li key={item}>{item}</li>
);
return (
<div>
{items}
</div>
)
}
key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识,建议使用数据中的 id 来作为元素的 key,数组元素中使用的 key 在其兄弟节点之间应该是独一无二的,不建议使用index作为key
注意:key可以向react传递信息,但不能向组件传递信息,即props.key读不到key的值
JSX 允许在大括号中嵌入任何表达式,所以我们可以内联 map()
return (
<div>
{ list.map(item =>
<li key={item}>{item}</li>
)}
</div>
)