html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test"></div>
</body>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel"> //声明babel
//创建虚拟dom元素
const dom = <h1>Hello React</h1>;
//将虚拟DOM渲染到真实的DOM中
ReactDOM.render(dom, document.getElementById('test'));
</script>
</html>
Code
1)React提供了一些API来创建一种 `特别` 的一般js对象
a.var element = React.createElement('h1', {id:'myTitle'},'hello')
b.上面创建的就是一个简单的虚拟DOM对象
2)虚拟DOM对象最终都会被React转换为真实的DOM
3)我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界面
javascript
<script type="text/babel"> //声明babel
//创建虚拟dom元素
let id = 'qjzxzxd';
//三种创建dom元素的方法
const dom = <h1>Hello React</h1>;
const dom2 = React.createElement('h2',{id:'name'},'MiChong')
const test3 =<h3 id={id.toUpperCase()}>{id.toUpperCase()}</h3>
//将虚拟DOM渲染到真实的DOM中
ReactDOM.render(dom, document.getElementById('test'));
ReactDOM.render(dom2,document.getElementById('name'));
ReactDOM.render(test3,document.getElementById('test3'));
</script>
JavaScript XML
Code
a.var ele = <h1>Hello JSX!</h1>
b.注意1: 它不是字符串, 也不是HTML/XML标签
c.注意2: 它最终产生的就是一个JS对象
javascript
<script type="text/babel">
//数组集合
let names = ['java','vue','React','Angular']
//新建DOM元素
let ul = (<ul>
{
names.map((name,index)=><li key={index}>{name}</li>)
}
</ul>);
//渲染DOM
ReactDOM.render(ul,document.getElementById('names'));
</script>
javascript
<script type="text/babel">
//1、定义组件
//方式1:工厂函数组件(简单组件)
function MyComponent() {
return <h1>MiChong</h1>;
}
//方式2、ES6类组件(复杂组件)
class MyComponent2 extends React.Component {
render() {
return <h2>qjzxzxd</h2>;
}
}
//2、渲染组件标签
ReactDOM.render(<MyComponent />, document.getElementById('test1'));
ReactDOM.render(<MyComponent2 />, document.getElementById('test2'));
</script>
==state
==
javascript
<script type="text/babel">
/**
* 需求:自定义组件
* 1、显示h2标题,初始文本为:你喜欢我
* 2、点击标题更新为:我喜欢你
*/
//1、定义组件
class Like extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {
isLikeMe: false
};
//将新增方法中的this强制绑定为组件对象
this.handleClick = this.handleClick.bind(this);
}
//新添加的方法:内部的this默认不是组件对象
//设置点击事件处理
handleClick() {
//得到状态
const isLikeMe = !this.state.isLikeMe;
//更新状态
this.setState ({isLikeMe});
}
//重写组件类方法
render() {
//读取状态
const {isLikeMe} = this.state;
return <h2 onClick={this.handleClick}>{isLikeMe ? '你喜欢我' : '我喜欢你'}</h2>;
}
}
//2、渲染组件标签
ReactDOM.render(<Like/>, document.getElementById('test'));
</script>
==props
==
javascript
<script type="text/babel">
/**
* 需求: 自定义用来显示一个人员信息的组件
1). 姓名必须指定
2). 如果性别没有指定, 默认为男
3). 如果年龄没有指定, 默认为18
*/
//1、定义组件
//方式一、使用工厂
function Person(props) {
return (
<ul>
<li>姓名:{props.name}</li>
<li>年龄:{props.age}</li>
<li>性别:{props.sex}</li>
</ul>
)
}
//方式二、使用ES6类组件
class Person extends React.Component{
render(){
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
)
}
}
//设置自定义标签的默认值
Person.defaultProps = {
name: '米虫',
age: 18,
sex: '男'
};
//设置自定义组件属性值的类型和必要性(要导入prop-types.js)
Person.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
};
//2、渲染组件标签
const p1 = {
name: 'MiChong',
age: 18,
sex: '男'
};
//ReactDOM.render(<Person name={p1.name} age={p1.age} sex={p1.sex}/>, document.getElementById('test'));
ReactDOM.render(<Person {...p1}/>, document.getElementById('test'));
ReactDOM.render(<Person age={p1.age} sex={p1.sex}/>, document.getElementById('test2'));
</script>
==refs
==
Code
a.<input type="text" ref={input => this.msgInput = input}/>
b.回调函数在组件初始化渲染完或卸载时自动调用
Code
a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件
b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
javascript
<script type="text/babel">
//1、定义组件
class MyComponent extends React.Component {
//固定格式
constructor(props){
super(props);
//添加自定义方法
this.showInput = this.showInput.bind(this);
this.handleBlur = this.handleBlur.bind(this);
}
//自定义事件方法
showInput(){
let input = this.refs.content;
//第一种写法的输出
//alert(input.value);
//第二种写法的输出
alert(this.input.value);
};
handleBlur(event){
alert(event.target.value);
}
render() {
return (
<div>
//第一种写法
<input type="text" ref="content"/>
//第二种写法
<input type="text" ref={input=>this.input = input}/>
<button onClick={this.showInput}>提示输入</button>
<input type="text" placeholder="失去焦点提示内容" onBlur={this.handleBlur}/>
</div>
)
}
}
ReactDOM.render(<MyComponent/>, document.getElementById('test'));
</script>
代码
javascript
<script type="text/babel">
//1、自定义组件
class App extends React.Component {
//初始化
constructor(props) {
super(props);
this.state = {
todos: ['java', 'html', 'go']
}
this.addTodos = this.addTodos.bind(this);
}
addTodos(todo) {
const {todos} = this.state;
todos.unshift(todo)
//更新状态
this.setState({todos})
}
render() {
const {todos} = this.state;
return (
<div>
<h1>Sample TODO Add</h1>
<Add count={todos.length} addTodos={this.addTodos}/>
<List todos={todos}/>
</div>
)
}
}
class Add extends React.Component {
constructor(props) {
super(props);
this.add = this.add.bind(this)
}
//自定义方法
add() {
//1、读取输入的数据
const inputValue = this.addInput.value.trim();
//2、列表添加数据
this.props.addTodos(inputValue)
//3、清除输入
this.addInput.value = ''
}
render() {
return (
<div>
<input type="text" ref={input => this.addInput = input}/>
<button onClick={this.add}>添加{this.props.count}</button>
</div>
)
}
}
class List extends React.Component {
render() {
const {todos} = this.props;
return (
<ul>
{todos.map((todo, index) => <li key={index}>{todo}</li>)}
</ul>
)
}
}
//2、渲染到真实的DOM中去
ReactDOM.render(<App/>, document.getElementById('sample'))
</script>
Code
a.受控组件: 表单项输入数据能自动收集成状态
b.非受控组件: 需要时才手动读取表单输入框中的数据
示意代码
javascript
<script type="text/babel">
/**
* 需求: 自定义包含表单的组件
1. 输入用户名密码后, 点击登陆提示输入信息
2. 不提交表单
*/
//1、自定义组件
class LoginForm extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {
pwd: ''
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleSubmit(event) {
const name = this.inputName.value;
const {pwd} = this.state;
//阻止时间的默认行为(提交)
event.preventDefault()
alert(`用户名${name},密码${pwd}`)
}
handleChange(event) {
//读取密码
const pwd = event.target.value;
//更新状态
this.setState({pwd})
}
render() {
return (
<form action="/test" onSubmit={this.handleSubmit}>
用户名:<input type="text" ref={input => this.inputName = input}/>
密码: <input type="password" value={this.state.pwd} onChange={this.handleChange}/>
<input type="submit" value="登录"/>
</form>
)
}
}
//2、渲染到真实的DOM中去
ReactDOM.render(<LoginForm/>, document.getElementById('sample'))
</script>
Code
a.第一次初始化渲染显示: ReactDOM.render()
* constructor(): 创建对象初始化state
* componentWillMount() : 将要插入回调
* render() : 用于插入虚拟DOM回调
* componentDidMount() : 已经插入回调
b.每次更新state: this.setSate()
* componentWillUpdate() : 将要更新回调
* render() : 更新(重新渲染)
* componentDidUpdate() : 已经更新回调
c.移除组件: ReactDOM.unmountComponentAtNode(containerDom)
* componentWillUnmount() : 组件将要被移除回调
Code
1)render(): 初始化渲染或更新渲染调用
2)componentDidMount(): 开启监听, 发送ajax请求
3)componentWillUnmount(): 做一些收尾工作, 如: 清理定时器
4)componentWillReceiveProps(): 后面需要时讲
javascript
<script type="text/babel">
/**
* 需求: 自定义组件
1. 让指定的文本做显示/隐藏的渐变动画
2. 切换持续时间为2S
3. 点击按钮从界面中移除组件界面
*/
//1、自定义组件
class Life extends React.Component {
constructor(props) {
super(props);
this.state = {
opacity: 1
};
this.destroyComponent = this.destroyComponent.bind(this);
}
destroyComponent(){
ReactDOM.unmountComponentAtNode(document.getElementById('sample'))
}
//设置循环定时器
componentDidMount() {
this.intervalId = setInterval(function () {
let {opacity} = this.state
opacity -= 0.1
if (opacity <= 0) {
opacity = 1
}
// 更新状态
this.setState({opacity})
console.log(opacity)
}.bind(this), 200)
}
//组件将要被移除回调
componentWillUnmount(){
clearInterval(this.intervalId);
}
render() {
const {opacity} = this.state;
return (
<div>
<h1 style={{opacity: opacity}}>{this.props.content}</h1>
<button onClick={this.destroyComponent}>change</button>
</div>
)
}
}
//2、渲染到真实的DOM中去
ReactDOM.render(<Life content="准时下班"/>, document.getElementById('sample'))
</script>
javascript
<script type="text/babel">
/*
验证:
虚拟DOM+DOM Diff算法: 最小化页面重绘
*/
class HelloWorld extends React.Component {
constructor(props) {
super(props)
this.state = {
date: new Date()
}
}
componentDidMount () {
setInterval(() => {
this.setState({
date: new Date()
})
}, 1000)
}
render () {
console.log('render()')
return (
<p>
Hello, <input type="text" placeholder="Your name here"/>!
<span>It is {this.state.date.toTimeString()}</span>
</p>
)
}
}
ReactDOM.render(
<HelloWorld/>,
document.getElementById('example')
)
</script>