写react项目要注意的事项
1,className一定是大写字母开头,例如:App-logo,App,App-header。
2,有关react元素的更新,唯一办法是创建新元素,然后重新将其传入ReactDOM.render()中重绘。
3,通过react官方的脚手架create-react-app新建项目时,你会发现里面没有任何的配置文件,其实webpack的配置文件被隐藏了,可以通过执行:npm run eject
将其暴露出来,暴露的文件夹有config和scripts两个文件夹。
4,react的脚手架项目中的index.html中并未引入src/index.js,那么是怎么联系起来的呢?
在config/paths.js中,以及webpack.config.js中:
在webpack.config.js中,最后生成一个可以注入script标签的index.html。
这些该有的配置react脚手架creat-react-app已经帮你配置并且隐藏,前端开发人员需要关注的只是src/文件夹下面的JS业务逻辑。
React使用JSX代替常规的javascript。JSX看起来像是XML的JS语法拓展,优点是,执行更快;类型安全,编译过程中就能发现错误;编写模板更加简单快速。
在react项目中使用JSX来描述用户界面,用来声明React中的元素;
const element = <h1>Hello,world!</h1>;
5,由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。
6,在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。
7,JSX 允许在模板中插入数组,数组会自动展开所有成员。
8,JSX中的注释需要写在花括号中 {/*注释...*/}。
9,在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。
10,const element = <HelloMessage /> 为用户自定义的组件。原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
11,复合组件:即创建多个组件来合成一个组件,把组件的不同功能点进行拆分。
12,使用react写了一个简单的弹窗功能,使用es6的class写法:
import React, { Component } from 'react'; import './OpenPacket.css'; function MaskCover(props){ return <div className="MaskCover" onClick={props.onClick} ></div> } class OpenPacket extends Component { constructor(){ super(); this.handleShow = this.handleShow.bind(this); this.handleHide = this.handleHide.bind(this); this.state = {isShow:false,date:new Date()}; } componentDidMount(){ this.timerID = setInterval(()=>{ this.tick() },1000) }
tick(){ this.setState({ date:new Date() }) } handleShow(){ this.setState({isShow:true}); } handleHide(){ this.setState({isShow:false}); } render(){ const isShow = this.state.isShow; let button; if(isShow){ button = <MaskCover onClick={this.handleHide} /> } return( <div> 我是主页面{this.state.date.toLocaleString()} <button onClick={this.handleShow}>打开遮罩</button> {button} </div> ) } } export default OpenPacket;
功能即点击打开遮罩按钮显示遮罩,点击遮罩背景关闭遮罩。主要注意的点:
(1)主页面是个class OpenPacket,遮罩组件是个function MaskCover,状态传递props,仅含有onClick属性,而点击事件的传递则是在子组件上面,通过props传递,在父组件当中定义真正的点击事件事务。
(2)主页面是es6的class写法,es6的class类似于构造函数,constructor方法就是构造方法,里面的this关键字代表实例对象。
class是通过extends关键字实现继承,ES5是通过修改原型链来实现继承的,上面定义的类OpenPakcet extends Component,也就是该类继承React组件的所有属性和方法。
(3)super表示父类的构造函数,用来新建父类的this对象。子类必须在constructor中调用super方法,否则新建实例时会报错!OpenPacket继承了React的Component类,而自己内部的this对象,必须通过父类的构造函数来塑造,得到与父类Component类同样的实例属性和方法,才能够正确渲染页面。如果不调用super方法,子类得不到this对象。ES5的继承实质是,先创建子类的实例对象this,然后将父类方法添加到this上面(Parent.apply(this);ES6不同之处在于,先将父类实例对象方法和属性加到this上面,所以必须先调用super方法,然后再用子类的构造函数修改this。
(4)上面的handleShow和handleHide方法是定义在OpenPacket对象的原型上面。因为单独调用handleShow和handleHide时候,this会指向所在运行的环境,所以要绑定this指向,方法有三,其他两种分别是:使用es6的箭头函数【推荐方法,简单好用】;还有就是在调用时候绑定this:
<PacketBG name={this.state.name} wishTxt={this.state.wishTxt} onClick={this.openPacket.bind(this,this.state.name)}/>
this 的本质就是:this跟作用域无关的,只跟执行上下文有关。
(5)React的State【状态】,this.state = {},React通过更新组件的state,进而重新渲染用户界面(不操作DOM);可以看到主页面的时间每分钟都在tick变化,主要就是通过定时器每一秒钟更新state中的date属性值,其中componentDidMount()为React的生命周期钩子,生命周期钩子有好几个,需要专门列一个专题来讲,只需了解react的数据更新是通过状态State来实现的,具体底层原理,等熟悉的差不多的时候再详细了解吧!
13,React的数据流自顶而下流动(单向数据流),怎么理解呢?
自顶向下单向流动,即从父组件到子组件,state和props是React组件的核心概念,如果顶层组件初始化props,那么React会向下遍历整棵组件树,重绘相关子组件;
而state只关心每个组件内部的状态或者局部状态,内部状态虽然经常改变,但是却跑不出组件,props和context用于组件中数据的传递,props支持逐层传递数据,而context则支持跨级传递。
state,props,context都是react中的数据载体。
14,react项目针对不闭合标签的错误,会立马报错,例如:Expected corresponding JSX closing tag for <p> ,然后整个页面报错,提醒你解决报错后再继续进行下去。
【未完待续】
新年flag1——写react项目像vue一样熟练,并且知晓简单的基础原理。