理解组件
在React中主要就是围绕着组件进行开发的,理解组件和组件化开发;
- 组件 -- 局部功能效果的资源和代码的集合;
- 组件化开发
(笔者理解)
组件,可以看作一块拼图,而页面也可看作由一块一块拼图拼成的,一块拼图是可大可小,可包含大块部分,也只包含一个按钮;
组件化开发,是万物皆是组件,有小组件拼建成大组件,大组件拼建成整个项目;
组件的分类
根据不同的分类标准进行分类:
- 代码书写方式:类式组件,函数式组件;
- 是否有state:简单组件,复杂组件;
- 表单是否维护到state:受控组件,非受控组件;
三大护法: state, props, ref
类式组件需要理解的三大概念: state, props, ref。
注意:官方推荐使用函数式组件,现还支持类式组件,但是学习也可从类式组件开始学习; 类式组件修改成函数式组件 推荐参考。
理解state
state 又被称为状态机,可以用来更新页面的显示,调用setState()会重新渲染组件;
- 使用
键值对(key: value)方式赋值; - 调用
setState()更新state;
理解props
组件属性之间传递数据;
- 数据是只读,可使用{表达式},但无法重新赋值;
- 批量传输props,
{...p}
理解ref
组件属性之间传递数据;
- 数据是只读,可使用{表达式},但无法重新赋值;
- 类型: ①字符串式;②回调式;③CreateRef()式
官方建议:
- 不推荐使用字符串型ref;
- 推荐使用后两种ref: 回调型ref, createRef, 其中各有各的优势,具体情况具体使用;
- 请勿过度使用ref
其他
其他概念的理解
- jsx(JavaScript XML)
- 虚拟DOM
- 高阶函数
- 函数的柯里化
jsx, JavaScript XML
【理解】jsx是 react 使用的语法,与 js 有区别,可理解为语法糖,计算机实际使用会翻译成 js;
【优点】相对 js,jsx 会①更简单,更易创建虚拟DOM;-- 简单,简单,还是简单;
【劣势】另外的学习成本, jsx的语法规则。
虚拟DOM
【理解】本质是 object 对象,最终会被转化成 真实DOM;
【优点】相对 真实DOM, ①更轻,没有杂乱的属性;
高阶函数
【理解】
- 两个条件满足任意一个,就是高阶函数:
- 若A函数,接收的参数是一个函数,那么A函数就是高阶函数;
- 若A函数,返回值是一个函数,那么A函数就是高阶函数;
【优点】通过复用来优化代码; 【常见高阶函数】 Promise, setTimeout, arr.map(), arr.filter()等
函数的柯里化
【理解】通过函数调用继续返回函数的方式,实现多次接收参数,最后统一处理的函数编码形式;
类式组件 -- 最简单版本
class myClassComponent extends React.Component {
render() {
return <h2>我是类式组件<h2/>
}
}
ReactDOM.render(<myClassComponent />, document.getElementById('root'))
函数式组件
function myFunctionComponent() {
return <h2>我是函数式组件<h2/>
}
ReactDOM.render(<myFunctionComponent/>, document.getElementById('root'))
复杂组件,动态修改天气 (标准形式 和 简写形式)
// 一个动态修改天气的组件 标准形式 = constructor + 其他
class Weather React.Component {
constructor(props) {
super(props)
this.state = {isHot: true}
this.changeHot = this.changeHot.bind(this) // 为函数bind this
}
changeHot() {
const isHot = this.state.isHot
this.setState({isHot:!isHot}) // 修改状态,调用setState修改
}
render() {
const {isHot} = this.state
return <h2 onClick={ this.changeHot }>今天很{ isHot ? '炎热': '凉爽' }<h2/>
}
}
ReactDOM.render(<Weather />, document.getElementById('root'))jsx
// 一个动态修改天气的组件, state 简写方式 使用箭头函数 =>{}
class Weather React.Component {
// 初始化状态
state = {isHot: true}
// 自定义方法,=()=>{}
changeHot = ()=>{
const isHot = this.state.isHot
this.setState({isHot:!isHot}) // 修改状态,调用setState修改
}
render() {
const {isHot} = this.state
return <h2 onClick={ this.changeHot }>今天很{ isHot ? '炎热': '凉爽' }<h2/>
}
}
ReactDOM.render(<Weather />, document.getElementById('root'))
非受控组件
// 一个登录的非受控组件, 现用现取
class Login React.Component {
handleSubmit = (event)=>{
event.preventDefault() //阻止表达提交
const {username, password} = this
alter(`用户名:${username.value}, 密码: ${password.value}`)
}
render() {
const {isHot} = this.state
return (
<from onSubmit={this.handleSumit}>
用户名:<input ref={c=>this.username=c} type="text" name="username"/>
密码:<input ref={c=>this.password=c} type="password" name="password"/>
<from/>
}
}
ReactDOM.render(<Login />, document.getElementById('root'))
受控组件
// 一个登录的受控组件, 推荐(不使用ref), 维护到了state, 受到了state控制
class Login React.Component {
state = {
username: '',
password: ''
}
saveUsername = (event)=>{
this.setState({username: event.target.value})
}
savePassword = (event)=>{
this.setState({username: event.target.value})
}
handleSubmit = (event)=>{
event.preventDefault() //阻止表达提交
const {username, password} = this.state
alter(`用户名:${username}, 密码: ${password}`)
}
render() {
const {isHot} = this.state
return (
<from onSubmit={this.handleSumit}>
用户名:<input onChange={this.saveUsername} type="text" name="username"/>
密码:<input onChange={this.savePassword} type="password" name="password"/>
<from/>
}
}
ReactDOM.render(<Login />, document.getElementById('root'))
props
class Person extends Component {
// 对属性进行限制
static propTypes = {
name: PropTypes.string.isrequred,
age: PropTypes.number
}
// 属性赋予默认值
static defaultProps = {
age: 18
}
render() {
const {name, age} = this.props
return (
<ul>
<li>姓名: {name} </li>
<li>年龄: {age+1} </li>
</ul>
)
}
}
ReactDOM.render(<Person name="jack" age={19}/>, document.getElementById('root'));
// 批量传递
const p = {name:"jack", age:18}
ReactDOM.render(<Person {...p}/>, document.getElementById('root'));
Ref
class Demo extends Component {
input3 = React.CreateRef()
showDate = ()=>{
const {input1} = this.refs
alter(input1.value)
}
render() {
const {name, age} = this.props
return (
<div>
<input ref="input1" type="text" placeholder="字符串Ref"/>
<button onclick={this.showData}></button>
<input ref={c=>this.input2=c} type="text" placeholder="回调Ref"/>
<input ref={this.input3=c} type="text" placeholder="createRef"/>
</div>
)
}
}
ReactDOM.render(<Demo />, document.getElementById('root'));
高阶函数
class Login extends Component {
state = {
'username':'',
'password':'',
}
// 高阶函数, 返回值是一个函数,可以保存用户名和密码等表单数据
// 应用了函数的柯里化技术
saveForm = (dataType) =>{
return (event)=>{
this.setsState({[dataType: event.target.value]})
}
}
handleSubmit = (event)=>{
event.preventDefault()
}
render() {
const {name, age} = this.props
return (
<form onSubmit={this.handleSubmit}>
用户名:<input onchange={this.saveForm('username')} type="text" name="username"/>
密码:<input onchange={this.saveForm('password')} type="password" name="password" />
<button}>登录</button>
</div>
)
}
}
ReactDOM.render(<Demo />, document.getElementById('root'));