react定义
- react用于构建用户界面的js库
- 特点
- 组件化模式, 声明式编码提高开发效率和组件复用率
- react native:可以做安卓或ios开发
- 使用了虚拟dom+diffing算法, 尽量避免和真实dom交互,提高了加载效率
- 虚拟dom和真实dom
- 虚拟dom本质上是object类型对象
- 虚拟dom比较轻 . 上面属性比真实dom少, 因为虚拟dom在react内部使用, 用不上那么多的属性
- 虚拟dom最终被转化成真实dom显示在页面上
jsx语法规则
- 定义虚拟dom不加引号
- 标签中混入js表达式要用花括号, {}
- 样式标签名不用class 要用className
- 内联样式: 要用style= {{key: v}} 的形式去写
- 只有一个根标签
- 标签必须闭合
- 标签首字母
(1) 标签首字母小写, 会在html中寻找同名标签, 如果没有则报错
(2) 标签首字大写,react会渲染对应的组件,如果组件未定义则报错
组件
- 函数式组件
- 函数式组件(用于定义简单组件),函数名就是组件名
- 函数组件内的this为undefined, 因为babel转换开启了严格模式
- 执行过程
- react解析组件标签找到组件
- 发现是函数定义的, 调用函数, 将虚拟dom转成真实dom并显示到页面中
- 类组件
- 条件
- react中使用类组件时需要继承react中的Component类
- 必须有render 且返回
- rander放在组件的原型对象中, 给组件的实例使用
- rander的this指向的是组件的实例对象
- 执行过程
- react解析组件名, 找到组件
- 发现是类定义的, new该类的实例, 并通过该实例调用原型的rander方法
- 将rander返回的虚拟dom转成真实dom随后呈现到页面
<div id="lenxi"></div>
<div id="test"></div>
function MyComponent() {
console.log(this);
retur (<h2>函数组件,适用于简单组件定义</h2>)
ReactDOM.render(<MyComponent/>, document.getElementById('lenxi'))
}
class MyComponent extends React.Component {
render() {
console.log(this)
return <h2>类定义组件 适用于复杂组件的定义</h2>
}
}
ReactDOM.render(<MyComponent /> document.getElementById('test'))
- 复杂组件和简单组件
- 复杂组件: 有状态(state)
- 简单组件: 没有状态(state)
- 组件实例的三大属性
- state
- state的值为对象,
- 通过更新组件state来更新页面显示(重新渲染组件)
- 组件render方法的this为组件实例对象
- 组件自定义方法的this为undefined
- 强制绑定this通过bind方法
- 赋值语句+箭头函数
- 状态数据不能直接修改
<div id="test"></div>
<script type="text/babel">
class Wather extends React.Component {
render() {
const { isHout, wind } = this.state
return <span onClick={this.clickTitle}>今天天气很{isHout ? '炎热' : '凉快'},{wind}</span>
}
state = {
isHout: true,
wind: '刮台风'
}
clickTitle = ()=> {
let isHout = this.state.isHout
this.setState({
isHout: !isHout
})
}
}
ReactDOM.render(<Wather />, document.getElementById('test'))
</script>
- props
- 类中构造器可写可不写, 一旦写了就要用super接收props否则this.props会为undefined
- 每个组件都有props属性,组件标签的属性保存在props中
- 作用: 通过标签属性向组件内传递变化数据,注意,组件内部不要修改props的数据
<div id="test"></div>
<script type="text/babel">
class Person extends React.Component {
render() {
const {name, age, sex} = this.props
return (
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>年龄: {age + 1}</li>
</ul>
)
}
}
let p = {name: 'haruki', age: 26, sex: '男'}
ReactDOM.render(<Person {...p}/>, document.getElementById('test'))
</script>
<div id="test"></div>
<script type="text/babel">
function Person(props) {
const { name, age, sex } = props
return (
<ul>
<li>姓名: {props.name}</li>
<li>性别: {props.sex}</li>
<li>年龄: {props.age + 1}</li>
</ul>
)
}
Person.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
speak: PropTypes.func
}
Person.defaultProps = {
sex: 'nan',
age: 13
}
let p = { name: 'haruki', age: 26, sex: '男' }
ReactDOM.render(<Person {...p} />, document.getElementById('test'))
</script>
- refs
- 标签可以定义ref来标识自己, 收集其真实dom到refs中.
<div id="test1"></div>
<script type="text/babel">
class Demo extends React.Component {
render() {
return (
<div>
{/*<input type="text" ref={(c) => { this.input1 = c }} placeholder="点击按钮提示" />*/}
<input type="text" ref={this.saveInput} placeholder="类绑定方式" />
<button onClick={this.showData}>提示左侧数据</button>
<input ref={c => this.input2 = c} type="text" onBlur={this.showData2} placeholder="失去焦点提示" />
</div>
)
}
saveInput=(c)=> {
console.log(c, 'ppppppp');
this.input1 = c
}
showData = () => {
console.log(this.input1, '点击按钮提示方法1', this.input1.value);
}
showData2 = () => {
console.log(this.input2, '点击按钮提示方法2', this.input2.value);
}
}
ReactDOM.render(<Demo />, document.getElementById('test1'))
</script>
<div id="test1"></div>
<script type="text/babel">
class Demo extends React.Component {
myRef = React.createRef()
myref2 = React.createRef()
render() {
return (
<div>
<input type="text" ref={this.myRef} placeholder="点击按钮提示" />
<button onClick={this.showData}>提示左侧数据</button>
<input ref={this.myref2} type="text" onBlur={this.showData2} placeholder="失去焦点提示" />
</div>
)
}
showData = () => {
console.log(this.myRef.current, this.myRef.current.value);
}
showData2 = () => {
console.log(this.myref2.current, this.myref2.current.value);
}
}
ReactDOM.render(<Demo />, document.getElementById('test1'))
</script>
事件处理
- 高阶函数: 如果一个函数符合下面两个的一个,就是高阶函数
- 若A函数, 接收的参数是一个函数,A就可以称之为高阶函数
- 若A函数, 调用的返回值是一个函数, A也可以称之为高阶函数
- 常见的高阶函数: Promise, setTimeout, 数组场景方法 map...
- 函数柯里化: 通过函数调用继续返回函数的方式, 实现多次接收参数最后统一处理的函数编码形式
<div id="test1"></div>
<script type="text/babel">
class Login extends React.Component {
render() {
return (
<form action="http://www.atguigu.com/" onSubmit={this.getInfor}>
用户名: <input onChange={this.saveForeDate('userName')} ref={c => this.userName = c} type="text" name='userName' />
密码: <input onChange={this.saveForeDate('passWord')} ref= {c => this.passWord = c} type="password" name="password" id="" />
<button>登录</button>
</form>
)
}
state = {
userName: '',
passWord: '',
}
saveForeDate = (dataType) => {
return (e) => {
console.log(dataType, e.target.value);
this.setState({[dataType]: e.target.value})
}
}
getInfor = (event) => {
event.preventDefault()
console.log(this.state );
}
}
ReactDOM.render(<Login/>, document.getElementById('test1'))
</script>