一. React特性
- 由Facebook创建的开源项目
- 属于MVC架构的视图层
- 添加JSX概念(JavaScript+XML)
- 函数式编程
二. JSX基本
1.特性:
- 由javascript+xml组成
- 事件包括属性变成小驼峰式写法。eg:onclick =>onClick
- 元素属性class变成了 classNam,label标签的元素属性for变成了htmlFor
- 自闭合标签必须以斜杠结尾-例如<img />
- 防止XSS攻击,渲染输入内容之前,会进行转义
- 可以在任意{}中放置任何 有效的JavaScript表达式,JSX也是表达式
2.基本写法:
//绑定变量和为内容嵌入表达式(使用用{}),以基本写法为示例
const name="wwww";
//基本写法
const element = (
<h1 className="greeting" myName={name}>
Hello, world!{name}
</h1>
);
//实际Babel转义写法
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
//上面两种写法最终生成对象(简化过的)
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}};3.渲染为页面(React只更新它需要更新的部分 )
//HTML文件
<div id="root"></div>
//JS文件
import React from 'react'
import ReactDOM from 'react-dom'
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));三.组件(必须以大写字母开头)
1.组件基本及props应用
/**
* props特点:
* 1.单项数据流:子组件不能直接修改父组件的值
* 2.可以传递 基本数据类型、JSX、函数
*/
//函数形式
function Comment(props) {
return (
<div className="Comment">
哈哈{props.name}
</div>
);
}
//class形式
class Comment extends React.Component {
render() {
return (
<div className="Comment">
哈哈{this.props.name}
</div>
);
}
}
2.class组件应用(生命周期、state基本)
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {name:"尼古拉斯"};
}
componentDidMount() {
console.log("挂载(组件第一次被渲染到 DOM 中)");
}
componentWillUnmount() {
console.log("卸载(组件被删除时)");
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.name}.</h2>
</div>
);
}
}3.state应用
- 修改:state的值只能通过setState修改
- props和state可能会异步更新(如何获取当前值) eg:
//第一种 this.setState((state, props) => ({ counter: state.counter + props.increment })); //第二种 this.setState(function (state, props) { return { counter: state.counter + .increment }; });
4.组件输写形式
1. <Clock />
2. <Clock> </Clock>四.事件处理
1.基本概念
- 不能通过returnfalse阻止默认行为(通过e.preventDefault)
- 事件默认合成参数e(不管有没有传递)
2.绑定this
//普通
this.handleClick = this.handleClick.bind(this);
//实验性写法class field
handleClick = () => { console.log('this is:', this);}
//箭头函数
<button onClick={(e) => this.handleClick(e)}></button>
//内部绑定
<button onClick={this.handleClick.bind(this)}></button>3.传递参数
1.<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
2.<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>五.条件渲染
1.{}里面条件渲染
//&&
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
//三目运算符
{isLoggedIn ?
<LogoutButton onClick={this.handleLogoutClick} /> :
<LoginButton onClick={this.handleLoginClick} />
}2.阻止组件渲染(返回null)
function WarningBanner(props) {
if (!props.warn) {
return null;//当return为null时阻止组件渲染
}
return (
<div className="warning">
Warning!
</div>
);
}六.key值
/**
* 特点:
* 1.万不得已不能使用索引作key,如果列表项目顺序变化,导致性能变差
* 2.key在全局不需要唯一
* 作用:
* 1.帮助React识别那些元素改变了
*/
//使用map遍历组件
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>七.表单
1.受控组件和非受控组件
//受控组件:以value={this.state} 和onChange改变的表单组件为受控组件
<input type="text" value={this.state.value} onChange={this.handleChange} />
//非受控组件:constructor中定义this.input =React.createRef(),在元素上ref={this.input}
//默认值:defaultValue
constructor(props) {
super(props);
this.input = React.createRef();
}
render() {
return (
<input type="text" ref={this.input} defaultValue="Bob"/>
);
}2.type="file":始终是非受控组件
八.组合(推荐组件组合的方式来实现组件间代码的重用)(一些用法思路)
1.props.child
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children} </div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}2.组件作参数
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div> );
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}