react从零到一

啦啦啦,今天开始就要正式开始我的react之路了,首先我用了create-react-app命令工具快速建了一个react项目,既然是从0到1,我就给src里面的内容删的干干净净。 写了一个最简单的:

//index.js
// 导入的React必须大写
import React from 'react';
import ReactDom from 'react-dom';
const h1 = <h1>hello world</h1>;  //会用babel进行转化 转化成React.createElement写法
// 是语法糖

ReactDom.render(h1,window.root)
复制代码

问题1: 为什么必须React大写?

问题2: reader咋实现的?

先来说问题一: 原来啊 jsx语法配合babel编译 然后调用React.createElement 那就自己写一个吧

let React = {
  createElement(type,props,...children){
    return {
      type,props,children
    }
  }
}

复制代码

问题2:render实现

// 当然这个render方法只是描述render最终干嘛了,实际在render中要远比这复杂,涉及到dom diff
let render = (vnode,container) => {
    if(typeof vnode == 'string') return container.appendChild(document.createTextNode(vnode));
    
    let {type,props,children} = vnode;
    let ele = document.createElement(type);
    for(let key in props) {
        ele.setAttribut(key,props[key]);
    }
    children.forEach((child)=>{
        render(child,ele)
    })
    container.appendChild(ele);
}
复制代码

接下来我们稍微复杂一点 渲染多个元素: 需要注意的是多个元素需要被一个标签包裹起来,我一般是

let ele = (
    <>
        <h1>你好</h1>
        <span>哈哈</span>
    </>
)
复制代码

上面只是简单的介绍,那jsx语法有以下这些规则:

  1. jsx 是可以包含js的语法 与html的写法是有一些区别的
  1. 如果渲染两个相邻的jsx元素 需要被外面的一个标签所包裹 <></>

  2. 行内样式的写法, jsx为了识别是html还是js 需要用 < { 来区分

  3. {} 表示的是写js 三元表达式,取值 ,(只要内容有返回值就可以显示)

  4. 属性的名字有变化 htmlFor => for / className=> class;

  5. 像v-html 把内容当成html 插入到页面中 dangerouslySetInnerHTML

  6. 注释只能写js注释

{/*当前是一个危险的操作 */}
<div dangerouslySetInnerHTML={{__html:str}}></div>
复制代码
  1. 列表渲染 map 数组是可以直接渲染的(不必须被包裹一个标签)
let arr = ['吃饭', '喝水', '睡觉']
let eleArr = arr.map((item) => {
   <li>{item}</li> 
})
ReactDOM.render(eleArr,window.root)  
复制代码
  1. 嵌套
let arr = ['吃饭', '喝水', '睡觉']
let eleArr = arr.map((item) => {
   <li>{item}</li> 
})
let obj = (
   <ul>
       {eleArr}
   </ul>
)
复制代码

以上就是jsx的基本用法,但是一个项目会很复杂,我们常常会封装很多组件,这样便于复用和维护,人家react文档中说了,在react中,一个函数就是一个组件。

在react中 组件名必须大写,和jsx,react元素进行区分

import React from 'react';
import ReactDom from 'react-dom';
function Clock() {
   return (<h1>当前时间</h1>)
}

ReactDom.render(<Clock></Clock>,window.root)
//或者这样 还可以和jsx嵌套
//ReactDom.render(<div><Clock></Clock></div>,window.root)
复制代码

其实在react中有两类组件: 所有组件都有属性

  1. 就是上面的函数组件
  • 没有this指向;
  • 没有生命周期;
  • 没有状态

函数组件属性的用法:

function Clock(props) {
   return (<h1>当前时间:props.date.toLocaleString()</h1>)
}

ReactDom.render(<Clock date={new Date()}></Clock>,window.root)
复制代码
  1. 类组件 类组件解决以上几个问题 this指向 生命周期 状态
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父类 提供更改状态的 setState方法
class Clock extends Component{
   <!--constructor(props) {-->
   <!--    super(props) //Component.call(this,props)-->
   <!--    this.state = {}-->
   <!--}-->
   state = {   //es7
       date: new Date().toLocaleString()
   }      
   render(){
       return <h1>时间是:{this.state.date}</h1>
   }
}
ReactDom.render(<Clock></Clock>,window.root)
复制代码

接下来我们了解一个非常重要的概念 生命周期 和vue一样 像上面的时钟案例,我们需要让时钟走动,最low的方法就是不断的render,也有用更改状态setState方法,但是什么时候去执行呢,这里就涉及到生命周期的问题了

  • componentWillMount 组件即将挂载
  • componentDidMount 组件已经挂载
  • componentWillReceiveProps 在接受父组件改变后的props需要重新渲染组件时,父亲render时 儿子必会render
  • shouldComponentUpdate 唯一用于控制组件重新渲染的生命周期,在这里return false可以阻止组件的更新
  • componentWillUpdate 组件即将更新
  • componentDidUpdate 组件已经更新
  • componentWillUnmount 组件即将卸载 那我们写了这么多似乎还缺少与用户的交互环节,例如用户点击触发了啥啥啥,就是绑定事件怎么绑,在react中绑定事件的方法名都是驼峰写法,还以上个例子为例:
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父类 提供更改状态的 setState方法
class Clock extends Component{
   state = {   //es7
       date: new Date().toLocaleString()
   }  
   handleClick = () => {   //妥善处理好了this指向问题
       console.log(this)
   } 
   componentDidMount() {
       setInterval(() => {
           this.setState({   //只会改动你要改动的,并不会干掉你没有要改动的
               date: new Date().toLocaleString()
           })
       },1000)
   }   
   render(){
       return <h1>时间是:{this.state.date} <span onClick={this.handleClick}>点击</span></h1> 
   }
}
ReactDom.render(<Clock></Clock>,window.root)
复制代码

这里留一个经典面试题: setState 批量更新 只针对同一个属性变量 不同的属性变量没有这个问题

解决方法:

1)setTimeout() 不推荐 2)prevState

this.setState((prevState) => {
   count: prevState.count+1
})

//等价下面
this.setState({
   count:this.state.count+1
},() => {
   <!--在下一个state操作-->
})
复制代码

总结一下:

  1. import React, {Component} from 'react'
import React, {Component} from 'react';
import ReactDom from 'react-dom'

class Count extends Component{
   constructor() {
       super()
   }
   state = {
       
   }
   
   render(){
       return (
           <div>
               
           </div>
       )
   }
}

ReactDom.render(<Count></Count>,window.root)
复制代码
  1. import ReactDom from 'react'
  2. jsx语法 属性名变化 htmlFor -> for class -> className,列表渲染 Map,组件名必须大写,函数组件, 给元素绑定事件(事件名驼峰写法)(this指向问题注意)以及生命周期
{this.props.xxx}
{this.state.xxx}
复制代码
  1. 属性和状态 属性不可更改 状态可以改但是必须是setState的方式 批量更新的问题: prevState或者回调函数方式

以上是自己学习入门React的入门笔记,分享给大家,当然还有很多不足之处希望大家指出,我会继续再接再厉更深入的从一到二

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值