React入门

以下内容,当具有ES6,JS语法,node环境,前端组件基础观点,写过java代码,包你3天上手React项目,下面最先…

react引见

  1. react: 一个js框架,让开发者能够在js中写html代码,也就是jsx语法,称为假造dom(类似一个js对象)
  2. react-dom: 挂载节点,将jsx写的假造dom变成真的dom
  3. render: 每次都是新旧假造dom之间举行比较,以后才会天生实在dom

建立react项目

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

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

A: 父组件 B: 子组件
在A.js文件中运用<B name={name} getName={this.getName}> 个中name为A文件中一个变量,getName为A文件中一个要领
在B.js文件中,可直接运用this.props.namethis.props.getNameconst { name, getName } = this.props来获得A中变量,或运转A中要领,末了一种最经常使用,这类体式格局是ES6中新增的解构赋值.
父->子 经由过程子标签上加上属性的体式格局,直接通报,在子重运用this.props来接住属性
子->父 经由过程在子中挪用父通报的要领来完成

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

  1. main页面担任ajax请求,拿总数据,为子组件准备好一切即插即用数据和要领,在运用select标签的时刻,悉数通报给子
  2. select页面,在this.props中担任解构一切数据和要领,直接运用,无需体贴逻辑完成
  3. main叫逻辑组件(智慧组件), select叫UI组件(蠢人组件)

JSX语法

  1. render中return中的代码都是JSX,和html代码类似.
  2. 在js中直接写html语法,也能够运用自定义标签,比方能够写本身组件,App组件能够写成 <App />,首字母必需大写开首,JSX标签中,大写开首,基础都是组件,小写开首基础是html标签.
  3. render顶用JSX语法写html代码,必需在最外层包含一个div,不然编译会报错,在16版本中,假如运用Fragment来示意占位符,在html中显现的时刻,可去掉组件最外层的谁人div,demo以下
<React.Fragment>
  // 你的jsx代码
</React.Fragment>
  1. 运用js表达式/js变量须要运用{}把表达式包裹起来,demo以下
// ES6 ``,${}加三目运算符可处置惩罚庞杂的css名字
<div className={`classA classB ${this.state.isSelect ? 'selected' : ''}`} />
// for轮回遍历请运用map要领,sortTableRows是state中一个变量
 {sortTableRows && sortTableRows.map(item => (
      <div key={item.id} className="table-row">
        <span>{item.title}</span>
        <span>{item.author}</span>
        <span>{item.comments}</span>
        <span>{item.points}</span>
        <span>
          <CancelButton onClick={() => onMiss(item.id)}>miss</CancelButton>
        </span>
      </div>
))}
  1. html标签中举行事宜绑定,事宜称号首字母必需大写,比方 onChange中C就是大写的
  2. 在html款式中,运用className来替代class
  3. 运用dangerouslySetInnerHTML={{__html: item}},可在提交数据的时刻,对数据中html标签举行转义处置惩罚
  4. <label for=”insertArea”>输入内容</label> for须要换成htmlfor

事宜绑定

jsx合成事宜绑定,js高阶函数,绑定的是函数,不能让函数立时实行
不带参数绑定,背面不能加(), 假如加,那函数会立时实行,而不是事宜发作时刻回调实行
带参数绑定,须要在一个匿名函数中写绑定函数

// 合成事宜绑定,不带参数
<li onClick={this.props.delItem}>{item}</li>
// 合成事宜绑定,带参数
<li onClick={(index) => this.props.delItem(index)}>{item}</li>

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接参数

  1. 子组件是UI组件,接完父组件数据直接运用,可直接在子组件props中直接运用父组件ajax请求猎取到的数据
  2. 子组件须要将父组件ajax数据赋值到本身的state中,只能在componentWillReceiveProps生命周期中处置惩罚,不能在constructor中处置惩罚,缘由: 父组件ajax请求最起码第二次render父组件,而子组件中constructor只会实行一次

上述体式格局处置惩罚体式格局比较贫苦,引荐运用体式格局3
3, 父组件担任供应数据和处置惩罚处置惩罚的函数,子组件只担任猎取数据,衬着页面,子组件事宜交互,也是经由过程props来挪用父组件中的函数(经常使用)

生命周期(主要)

《React入门》
以下是运用场景和注重点
组件挂载阶段(只会实行一次,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指向

  1. 自定义函数的时刻,写自定义函数,须要在constructor中举行函数this指向的绑定
  2. 在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
* <Search value={searchTerm} onSubmit={this.onSubmit} onChange={this.onChange}>查询</Search>  children的值就是查询
*/
const Search = ({value, onChange, onSubmit, children}) => {
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input type='text' value={value} onChange={onChange}/>
        <button type='submit'>{children}</button>
      </form>
    </div>
  )
}

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 (
    <div className='time-slider'>
      <Slider max={getMax()} marks={getMarks()} defaultValue={getDefaultValue()} value={getDefaultValue()} tipFormatter={formatter} onChange={onTimeChange}/>
    </div>
  )
}

export default TimeSlider

两款chrome插件

  1. React Developer Tools // F12,检察每一个react组件中state和props的值
  2. Redux DevTools // F12,检察redux中store的值
    原文作者:wujiedong
    原文地址: https://segmentfault.com/a/1190000019058420
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞