资讯专栏INFORMATION COLUMN

React入门

VioletJack / 778人阅读

摘要:以下内容当具备语法环境前端组件基础概念写过代码包你天上手项目下面开始地址项目结构如下的方式值得借鉴介绍一个框架让开发者可以在中写代码也就是语法称为虚拟类似一个对象挂载节点将写的虚拟变成真的每次都是新旧虚拟之间进行比较之后才会生成真实创建项

以下内容,当具备ES6,JS语法,node环境,前端组件基础概念,写过java代码,包你3天上手React项目,下面开始...

demo地址

https://gitee.com/tonysb/lear...
项目结构如下,Button的方式值得借鉴

react介绍

react: 一个js框架,让开发者可以在js中写html代码,也就是jsx语法,称为虚拟dom(类似一个js对象)

react-dom: 挂载节点,将jsx写的虚拟dom变成真的dom

render: 每次都是新旧虚拟dom之间进行比较,之后才会生成真实dom

创建react项目

命令行使用 npx create-react-app my-app-name 即可创建项目

react中组件(子父之间传值)

A: 父组件 B: 子组件
在A.js文件中使用 其中name为A文件中一个变量,getName为A文件中一个方法
在B.js文件中,可直接使用this.props.namethis.props.getNameconst { name, getName } = this.props来得到A中变量,或运行A中方法,最后一种最常用,这种方式是ES6中新增的解构赋值.
父->子 通过子标签上加上属性的方式,直接传递,在子重使用this.props来接住属性
子->父 通过在子中调用父传递的方法来完成

具体使用场景: 一个页面右上角挂载一个三级联动选项卡(三级数据从接口获取),main作为父组件主页面,select作为子组件三级选项卡页面

main页面负责ajax请求,拿总数据,为子组件准备好所有即插即用数据和方法,在使用select标签的时候,全部传递给子

select页面,在this.props中负责解构所有数据和方法,直接使用,无需关心逻辑实现

main叫逻辑组件(聪明组件), select叫UI组件(笨蛋组件)

JSX语法

render中return中的代码都是JSX,和html代码相似.

在js中直接写html语法,也可以使用自定义标签,比如可以写自己组件,App组件可以写成 ,首字母必须大写开头,JSX标签中,大写开头,基本都是组件,小写开头基本是html标签.

render中用JSX语法写html代码,必须在最外层包括一个div,不然编译会报错,在16版本中,如果使用Fragment来表示占位符,在html中显示的时候,可去掉组件最外层的那个div,demo如下


  // 你的jsx代码

使用js表达式/js变量需要使用{}把表达式包裹起来,demo如下

// ES6 ``,${}加三目运算符可处理复杂的css名字
// for循环遍历请使用map方法,sortTableRows是state中一个变量 {sortTableRows && sortTableRows.map(item => (
{item.title} {item.author} {item.comments} {item.points} onMiss(item.id)}>miss
))}

html标签中进行事件绑定,事件名称首字母必须大写,比如 onChange中C就是大写的

在html样式中,使用className来代替class

使用dangerouslySetInnerHTML={{__html: item}},可在提交数据的时候,对数据中html标签进行转义处理

for需要换成htmlfor

事件绑定

jsx合成事件绑定,js高阶函数,绑定的是函数,不能让函数马上执行
不带参数绑定,后面不能加(), 如果加,那函数会马上执行,而不是事件发生时候回调执行
带参数绑定,需要在一个匿名函数中写绑定函数

// 合成事件绑定,不带参数
  • {item}
  • // 合成事件绑定,带参数
  • this.props.delItem(index)}>{item}
  • 表单交互(input)

    1, state中设置searchTerm变量,用来填充input中value值
    2, 绑定input中onChange事件,获取event对象中value值,将该值set到searchTerm变量中

    state和props和render

    state: 组件自己内部维护数据,每次更新只需要关系需要更改的数据
    1, set数据不依赖之前的数据,直接调用setState

    this.setState({ 
                   foo: bar 
                })

    2, set数据依赖之前数据,一定要使用带参数调用setState

    this.setState((prevState, props) => (
        // 你的代码  
    ))
    
    // bad
    // setState是异步,代码中多个set,有可能fooCount和barCount已经被改变
    const { fooCount } = this.state
    const { barCount } = this.props
    this.setState({ count: fooCount + barCount })
    // good
    this.setState((prevState, props) => (
        count: prevState.fooCount + props.barCount
    ))

    props: 父->子,所有传递过来的数据都附加在props中,子在props中可以拿到所有父传递过来的数据
    render: 只要state进行set操作,render一定会执行,包括父state进行set之后,父和子的render都会被执行

    ajax接参数

    子组件是UI组件,接完父组件数据直接使用,可直接在子组件props中直接使用父组件ajax请求获取到的数据

    子组件需要将父组件ajax数据赋值到自己的state中,只能在componentWillReceiveProps生命周期中处理,不能在constructor中处理,原因: 父组件ajax请求最起码第二次render父组件,而子组件中constructor只会执行一次

    上述方式处理方式比较麻烦,推荐使用方式3
    3, 父组件负责提供数据和处理处理的函数,子组件只负责获取数据,渲染页面,子组件事件交互,也是通过props来调用父组件中的函数(常用)

    生命周期(重要)


    以下是使用场景和注意点
    组件挂载阶段(只会执行一次,render除外)
    constructor(): 设置state,获取父组件props,并初始化自己的state,并绑定函数中this指向
    componentWillMount(): 不能获取页面dom元素,目前还没用过
    render():渲染页面,不做运算,到这里为止,所有数据都应该是经过处理可直接使用的数据
    componentDidMount(): 可获取dom元素,ajax请求放这里,调用setState,设置dom元素监听,绘制canvas
    组件更新阶段(state或props发生变化)
    componentWillReceiveProps(nextProps): nextProps为更新新属性,可进行新旧属性对比,也可以根据新数据来计算和设置自己的state
    shouldComponentUpdate(nextProps, nextState): 返回布尔值,可做渲染优化,根据场景决定是否渲染该组件,不要调用setState
    componentDidUpdate(prevProps, prevState): 操作 DOM 或者执行更多异步请求的机会
    componentWillUnmount: 取消网络请求,删除监听,一些收尾工作,不要调用setState

    react中this指向

    自定义函数的时候,写自定义函数,需要在constructor中进行函数this指向的绑定

    在constructor中进行this指向绑定,然后写正常函数

    // 方式1
      getTodoItem = () => {
        // 你的逻辑
      }
    // 方式2
     constructor(props) {
        super(props)
        this.inputOnChange = this.inputOnChange.bind(this)
      }
     inputOnChange() {
        // 你的逻辑
      }
    组件类型

    ES6类组件: 有this,props,有state,有生命周期,根据设计图,一般当作父组件使用,从接口拿数据,计算成品数据,编写事件函数来处理数据
    无状态组件(纯函数): 接收输入(props),输出jsx组件实例,没有this,没有生命周期,没有state,可根据props中的数据来计算符合自己要求的数据(组件中直接调用方法),
    props中可以传递数据,也可以传递函数,一般当做子组件使用,demo如下

    import React from "react"
    
    /*查询表单组件
    * Search在使用的时候,标签中间就是children
    * 查询  children的值就是查询
    */
    const Search = ({value, onChange, onSubmit, children}) => {
      return (
        
    ) } export default Search
    import React from "react"
    import {Slider} from "antd"
    import moment from "moment"
    import "./style.less"
    
    /*
    * 时间轴无状态组件
    * timeData: 时间数组列表
    * timeChange: 时间轴change事件的回调
    * worktime: 当前选中时间
    * */
    const TimeSlider = ({timeData, timeChange, worktime}) => {
    
      /*
      * 获取时间轴当前选中值
      * */
      const getDefaultValue = () => {
        const { id } = times.find(item => {
          return item.dateTime === worktime
        })
        return id
      }
    
      /*
      * 获取时间轴的总长度
      * */
      const getMax = () => {
        return timeData.length
      }
    
      /*
      * 获取时间轴显示的time数据
      * 格式:
      * {
      *  0: "2019-11-11"
      *  24: "2019-11-12"
      *  23: "2019-11-13"
      * }
      * */
      let times = []
      const getMarks = () => {
        let dates = []
        console.log("timeData len", timeData.length)
        timeData.map((item, index) => {
          const time = {id: index, dateTime: item}
          times.push(time)
          dates.push(moment(item).format("YYYY-MM-DD"))
        })
        const newDates = [...new Set(dates)]
    
        console.log("newDates", newDates)
        let marks = {}
        let datesAmount = []
        newDates.map(item => {
          const amount = getDateAmount(item, timeData)
          const temp = {date: item, amount: amount}
          datesAmount.push(temp)
        })
    
        for (let i = 0,length = datesAmount.length; i < length; i++) {
          const date =  {
            style: {
              color: "#fff",
              marginLeft: 0
            },
            label: moment(datesAmount[i].date).format("MM/DD"),
          }
          if (i === 0) {
            //const mark =  JSON.parse(`{"0":"${date}"}`)
            const mark = {0: date}
            Object.assign(marks, mark)
          } else {
            const index = i - 1
            const lastAmount = getLastDateAmount(index, datesAmount)
           // const mark =  JSON.parse(`{"${lastAmount}":"${date}"}`)
            const mark =  { [lastAmount]: date }
            Object.assign(marks, mark)
          }
        }
        return marks
      }
    
      /*
      * 根据 2019-11-11来获取 数据 ["2019-11-11 11:11:11"] 对应的小时数量
      * */
      const getDateAmount = (date, timeData) => {
        let amount = 0
        for (let i = 0,length = timeData.length; i < length; i++ ) {
          const item = timeData[i]
          if (item.includes(date)) {
            amount = amount + 1
          }
        }
        return amount
      }
    
      /*
      * 获取当前index往前推一个的所有小时数量
      * */
      const getLastDateAmount = (index, datesAmount) => {
        let sum = 0
        for (let i = 0; i <= index; i++) {
          sum = sum + datesAmount[i].amount
        }
        return sum
      }
    
    
      const formatter = (value) => {
        const time = times.find(item => {
          return item.id === value
        })
        return moment(time.dateTime).format("HH:mm")
      }
    
      const onTimeChange = (value) => {
        const time = times.find(item => {
          return item.id === value
        })
        timeChange(time.dateTime)
      }
    
      return (
        
    ) } export default TimeSlider
    两款chrome插件

    React Developer Tools // F12,查看每个react组件中state和props的值

    Redux DevTools // F12,查看redux中store的值

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/104066.html

    相关文章

    • React 入门学习笔记整理目录

      摘要:入门学习笔记整理一搭建环境入门学习笔记整理二简介与语法入门学习笔记整理三组件入门学习笔记整理四事件入门学习笔记整理五入门学习笔记整理六组件通信入门学习笔记整理七生命周期入门学习笔记整理八入门学习笔记整理九路由React 入门学习笔记整理(一)——搭建环境 React 入门学习笔记整理(二)—— JSX简介与语法 React 入门学习笔记整理(三)—— 组件 React 入门学习笔记整理(...

      daryl 评论0 收藏0
    • React 可视化开发工具 Shadow Widget 非正经入门(之一:React 三宗罪)

      摘要:前言非正经入门是相对正经入门而言的。不过不要紧,正式学习仍需回到正经入门的方式。快速入门建议先学会用拼文写文档注册一个账号,把库到自己名下,然后用这个库写自己的博客,参见这份介绍。会用拼文写文章,相当于开发已入门三分之一了。 本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点,既作为用户手册的补充,也从更本质角度帮助大家理解 Shadow Widget 为什么这...

      dongxiawu 评论0 收藏0
    • React入门之脚手架搭建项目

      摘要:前言写此系列博客的目的是对所学知识点的总结和梳理,包括填坑方案分享,希望能帮助到还并不会使用的开发者入门官方文档中文文档社区项目搭建按照官方提供的搭建项目全局安装或全局安装后可以使用这条命令创建名为的项目启动 前言 写此系列博客的目的是对所学React知识点的总结和梳理,包括填坑方案分享,希望能帮助到还并不会使用React的开发者入门React React官方文档React中文文档R...

      BingqiChen 评论0 收藏0
    • 快速入门React

      摘要:考虑到是快速入门,于是乎我们就记住一点,当修改值需要重新渲染的时候,的机制是不会让他全部重新渲染的,它只会把你修改值所在的重新更新。这一生命周期返回的任何值将会作为参数被传递给。 安装react npm install creat-react-app -gshowImg(https://segmentfault.com/img/remote/1460000015639868); 这里直...

      figofuture 评论0 收藏0
    • 前端学习资源整理

      稍微整理了一下自己平时看到的前端学习资源,分享给大家。 html MDN:Mozilla开发者网络 SEO:前端开发中的SEO css 张鑫旭:张鑫旭的博客 css精灵图:css精灵图实践 栅格系统:详解CSS中的栅格系统 媒体查询:css媒体查询用法 rem布局:手机端页面自适应布局 移动前端开发之viewport的深入理解:深入理解viewport 淘宝前端布局:手机淘宝移动端布局 fl...

      siberiawolf 评论0 收藏0

    发表评论

    0条评论

    VioletJack

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <