美文网首页
react学习之路

react学习之路

作者: 余音绕梁_0809 | 来源:发表于2019-11-07 14:44 被阅读0次

一、简介

image.png

1、安装Node.js

使用React.js是可以用最原始的<Script>标签进行引入的,但是这实在是太low了,工作中也不会有这种形式进行引入。所以在学习的时候,我们就采用脚手架形式的安装。这就需要我们安装Node.js,用里边的npm来进行安装。

安装Node只需要进入Node网站,进行响应版本的下载,然后进行双击安装就可以了。

Node中文网址:http://nodejs.cn/ (建议你在这里下载,速度会快很多)

需要你注意的是,一定要正确下载对应版本,版本下载错误,可是没有办法使用的哦。

Node.js 安装好以后,如果是Windows系统,可以使用 Win+R打开运行,然后输入cmd,打开终端(或者叫命令行工具)。

输入代码:

node -v 

如果正确出现版本号,说明Node安装成功了,需要说明的是,你的版本号可能跟我视频中的有所不同,这无关紧要。

然后再输入代码:

npm -v

如果正确出现版本号,说明npm也是没问题的,这时候我们的Node.js安装就算完成了。

2、脚手架的安装

Node安装好之后,你就可以使用npm命令来安装脚手架工具了,方法很简单,只要打开终端,然后输入下面的命令就可以了。

npm install -g create-react-app

create-react-app是React官方出的脚手架工具,其实有很多第三方的脚手架工具,也有很多优秀的。但是作为初学者为了减少踩坑,所以我们使用官方的脚手架。

3、创建第一个React项目

脚手架安装好以后,就可以创建项目了,我们在D盘创建一个ReactDemo文件夹,然后进入这个文件夹,创建新的React项目。

D:  //进入D盘
mkdir ReactDemo  //创建ReactDemo文件夹
create-react-app demo01   //用脚手架创建React项目
cd demo01   //等创建完成后,进入项目目录
npm start   //预览项目,如果能正常打开,说明项目创建成功

报错解决备注:

npm install -g create-react-app
在mac上安装时,没有效果,使用了    cnpm install -g create-react-app

对应的在使用  create-react-app demo01 时,同样没有效果,此时应将cnpm设置为默认的安装方式
npm config set registry https://registry.npm.taobao.org

二、代码之路

import React,{Component} from 'react';
等价于 下面的两行(es6解构赋值)
import React from 'react';
const Component = React.Component

1、JSX简介

JSX就是Javascript和XML结合的一种格式。React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM,当遇到<,JSX就当作HTML解析,遇到{就当JavaScript解析.

比如我们写一段JSX语法

<ul className="my-list">
    <li>JSPang.com</li>
    <li>I love React</li>
</ul>

比如我们以前写一段代码JS代码:

var child1 = React.createElement('li', null, 'JSPang.com');
var child2 = React.createElement('li', null, 'I love React');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);

从代码量上就可以看出JSX语法大量简化了我们的工作。

2、组件和普通JSX语法区别

这个说起来也只有简单的一句话,就是你自定义的组件必须首写字母要进行大写,而JSX是小写字母开头的。
这个也算是一个比较重要的知识点吧。

注意: 这里的HTML类名 要用className定义,不能使用class

3、 JSX使用注意事项

在React中,最外层需要有一个包裹元素,最外层不想有包裹元素的话,使用<Fragment>标签。

要想使用<Fragment>,需要先进行引入。

import React,{Component,Fragment } from 'react'

然后把最外层的<div>标签,换成<Fragment>标签。

import React,{Component,Fragment } from 'react'

class Xiaojiejie extends Component{
    constructor (props) {
      super(props) //调用父类的构造函数,固定写法
      this.state = {
        inputValue: '',
        list: ['haha', '精油推背'],
        ceshiHTML:'<h1>ssss</h1>'
      }
    }
    render(){
        return  (
            <Fragment>
              {/* 正确注释的写法 */}
               <label htmlFor="jspang">加入服务:</label>
               <div><input id='jspang' /> <button> 增加服务 </button></div>
               <ul>
                   <li>头部按摩</li>
                   <li>精油推背</li>
                   <li dangerouslySetInnerHTML={{__html:this.state.ceshiHTML}}></li> 
               </ul> 
            </Fragment>
        )
    }
}
export default Xiaojiejie 

注意:
1、其实这边的写法,类似于Vue的组件写法,html必须有一个最外层html包裹;此时如果你不需要最外层的html,可以将最外层的html用Fragment代替,vscode不会报错,同时在html中也不会有最外层的html显示
2、jsx的注释写法,{/* 正确注释的写法 */}
3、HTML类名要把class换成className,它是防止和js中的class类名冲突
4、dangerouslySetInnerHTML={{__html:XX}},如果XX是含html标签的,则可以解析html标签;
5、label标签不能使用for。它容易和javascript里的for循环混淆,会提示你使用htmlFor。(想点击“加入服务”直接可以激活文本框,方便输入。按照html的原思想,是直接加ID就可以了)

4、方法定义以及使用

import React,{Component,Fragment} from 'react';

class Xiaojiejie extends Component{
  constructor (props) {
    super(props) //调用父类的构造函数,固定写法
    this.state = {
      inputValue: '',
      list: ['头部按摩', '精油推背']
    }
  }
  render() {
    return(
      <Fragment>
        <div>
          <input value = {this.state.inputValue} onChange={this.inputChange.bind(this)}/> 
          <button onClick={this.addList.bind(this)}> 增加服务 </button>
        </div>
        <ul>
            {
              this.state.list.map((item, index) => {
                return (
                  <li key={item + index}
                  onClick = {this.deleteItem.bind(this, index)}
                  > {item} </li>
                )
              })
            }
        </ul> 
    </Fragment>
    )
  }
  inputChange(e) {
    this.setState({
      inputValue: e.target.value
    })
  }
  addList(){
    this.setState({
      list: [...this.state.list, this.state.inputValue],
      inputValue: ''
    })
  }
  deleteItem(index){
    console.log(index)
    let list = this.state.list
    list.splice(index,1)
    this.setState({
      list: list
    })
  }
}
export default Xiaojiejie

注意:
1、onChange是一个change事件,在React里,事件的绑定要使用小驼峰命名法。
2、这里的.bind(this),是ES6的语法,此时里面需要绑定this,否则在方法中使用this时,this的指向并不是当前的dom元素。
3、React中的循环是写在{}中的,在循环中绑定方法的话,需要写在return()的括号中,此时若想要传值,和this一样写在.bind()中,在定义方法的时候,可以带参数,可以拿到。类似vue
4、React中对state里面的数据进行操作时,不能直接写this.state.XX = '',需要使用this.setState({XX:''})
5、React是禁止直接操作state的,即我们在删除this.state.list中的数据时,是将this.state.list赋值给一个新的数组,去操作这个新数据,最后将新数组的值赋值给this.state.list

5、父子组件之间的通信

  • 父组件
import React, { Component } from 'react';
// 这里的引入 FoodItem首字母要大写,不然会报错
import FoodItem from './foodItem'
import  './shitang.css'

class Shitang extends Component {
  constructor(props){
    super(props)
    this.state = {
      foodValue: '',
      foodList: ['土豆丝', '土豆片', '土豆块', '土豆泥']
    }
    this.addFood = this.addFood.bind(this)
    this.inputChange = this.inputChange.bind(this)
    this.deleteItem = this.deleteItem.bind(this)
  }
  render() { 
    return (  
      <div>
        <label htmlFor='food'>添加新菜品</label>
        <input
        id='food'
        vaule={this.state.foodValue}
        onChange={this.inputChange}
        // ES6语法 -- 绑定DOM元素
        ref={ input => {this.input = input}}></input>
        <button onClick={this.addFood}>添加菜品</button>
        <ul>
          {
            this.state.foodList.map((item, index) => {
              return (
                <li 
                key={item + index}
                // onClick={this.deleteItem(index)} --- 使用时会立即执行deleteItem方法
                onClick={() => this.deleteItem(index)}
                >{item}</li>
              )
            })
          }
        </ul>
        {/* 这里使用了子组件 FoodItem */}
        <ul className='food' ref = {ul => {this.ul = ul}}>
          {
            this.state.foodList.map((item, index) => {
              return (
                <FoodItem 
                key={item + index}
                content ={item}
                index = {index}
                onClick={() => this.deleteItem(index)}
                deleteItem = {this.deleteItem}
                />
              )
            })
          }
        </ul>
      </div>
    ); 
  }
  inputChange () {
    this.setState({
      foodValue: this.input.value
    })
  }
  addFood () {
    this.setState({
      foodList: [...this.state.foodList,this.state.foodValue]
    })
    console.log(this.ul.querySelectorAll('li').length)
    // 现象: 此时调用打印的值是与实际不相符的 
    // 原因: this.setState这个方法是异步的,当执行打印的时候,this.setState可能并没有执行完成
    // 解决方案: this.setState有一个回调函数,此时将打印放到回调函数中即可
    // this.setState({
    //   foodList: [...this.state.foodList,this.state.foodValue]
    // },() => {
    //   console.log(this.ul.querySelectorAll('li').length)
    // })
    this.input.value = ''
  }
  deleteItem (index) {
    let list = this.state.foodList
    list.splice(index, 1)
    this.setState({
      foodList: list
    })
  }
}
 
export default Shitang;
  • 子组件
import React, { Component } from 'react';
import PropTypes from 'prop-types'

class foodItem extends Component {
  constructor(props){
    super(props)
    this.deleteFood = this.deleteFood.bind(this)
  }
  render() { 
    return (  
      <li 
      onClick={this.deleteFood}
      >
      {this.props.username}--- 会做的菜 ---{this.props.content}
      </li>
    );
  }
  deleteFood () {
    this.props.deleteItem(this.props.index)
  }
}
// 校验传递值 PropTypes  使用时 需先引入
foodItem.propTypes ={
  // 必传值的校验 ---isRequired
  content:PropTypes.string.isRequired,
  deleteItem:PropTypes.func,
  index:PropTypes.number,
  username: PropTypes.string.isRequired
}
// 若设置必传值,又担心没有值则可使用默认值defaultProps;
// 此时若是父组件没有传递username这个参数,则会使用默认值渲染
foodItem.defaultProps = {
  username: '小花'
}
 
export default foodItem;
image.png

注意:
1、事件绑定的另一种写法:onClick={this.addFood.bind(this)} ====> onClick = {this.addFood};前面的写法是在绑定事件的时候将this指向一起绑定;后面的写法,this的指向是在constructor方法中绑定
this.addFood = this.addFood.bind(this)
2、在引入子组件时,子组件名称首字母要大写import FoodItem from './foodItem',否则会报错
3、在使用 onClick={this.deleteItem(index)}进行传参的时候,会立即执行deleteItem方法,并不是点击后触发deleteItem方法。修改为onClick={() => this.deleteItem(index)} 原因暂时不知道,但是这样可以解决
4、ref来绑定DOM元素:绑定时最好使用ES6语法中的箭头函数。 ref={ ul => {this.ul = ul}},此时需要注意:若此时我们想要获取ul下面li的个数,且li是动态生成的(addFood方法中),若是在this.setState()方法后执行,则会出现与实际不符的情况。 原因是this.setState()方法是异步加载的,当执行打印的时候,this.setState()可能并没有执行完成。解决方案:React的this.setState()方法提供了回调函数,写在回调中即可。
5、React有一个特性是单项数据流,即父组件向子组件传递一个数组的话,是可以传递成功的,但是这个数组在子组件中只可使用不可改变。
6、父组件向子组件传递参数和方法:在父组件中的子组件上传递(如下),传递的数据在子组件中用this.props.XXX接收,方法也一样

<FoodItem 
  key={item + index}
  content ={item}
  index = {index}
  onClick={() => this.deleteItem(index)}
  deleteItem = {this.deleteItem}
/>

7、在子组件中校验传递值( PropTypes) 使用时 需先引入import PropTypes from 'prop-types'

//foodItem --- 子组件的类名
foodItem.propTypes ={
  // 必传值的校验 ---isRequired
  content:PropTypes.string.isRequired,
  deleteItem:PropTypes.func,
  index:PropTypes.number,
  username: PropTypes.string.isRequired
}
// 若设置必传值,又担心没有值则可使用默认值defaultProps;
// 此时若是父组件没有传递username这个参数,则会使用默认值渲染
foodItem.defaultProps = {
  username: '小花'
}

8、子组件向父组件传递数据时,需要在子组件中使用this.props.xx(val)(其中val为需要传递给父组件的数据,可以为单个数据,也可以为对象的形式;xx表示在父组件中绑定的是方法名,这个方法在绑定之后也需要在父组件的constructor中使用bind()方法绑定this的指向)

6、react的生命周期

Initialization:初始化阶段。
Mounting: 挂载阶段。
Updation: 更新阶段。
Unmounting: 销毁阶段

image.png

备注:以上来自技术胖博主,以及自己的遇到的问题

相关文章

  • React Native

    React Native之路(一)Windows下安装配置 - 简书 react native学习笔记0——win...

  • react学习之路

    一、简介 1、安装Node.js 使用React.js是可以用最原始的 标签进行引入的,但是这实在是太low了,工...

  • React学习之路

    React学习网站:http://caibaojian.com/react/ 蚂蚁金服Ant Design组件:h...

  • React Native 学习之路

    React 相关资料 React Components React Properties React State ...

  • React Native学习之路(6) - React Nati

    (1)单一组件的生命周期再学习 **一 ( 组件初始化 ): ** (1) getDefaultProps:获取初...

  • Create-React-App 进阶笔记

    CreateReactApp 是学习 React 的必经之路,其本身也值得深入学习,本文记录了如何给该脚手架添加一...

  • React01-开始

    在记录react的学习之路开始,我想先谈谈为什么会有react假如有一个页面,页面上有一个dom,要操作这个dom...

  • 后端学习React之路(一)

    进入新公司后发现后端要担任前端的活干,使用的前端框架是React,对于一个只在毕业设计写过前端的一开始是非常迷茫...

  • React-- 开篇路线

    React 学习路线图 ,一个 ios App 开发者的前端之路 从前端小白,打卡前行,并写下自己的学习体验

  • React 深入系列1:React 中的元素、组件、实例和节点

    文:徐超,《React进阶之路》作者 授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中...

网友评论

      本文标题:react学习之路

      本文链接:https://www.haomeiwen.com/subject/qvjsbctx.html