从0开始React

266 阅读5分钟

React是用于构建用户界面的Javascript库(并不是框架)需要Redux/React-router。(描述页面状态的数据结构) 只是视图层框架,大型项目还需要数据框架。

React组件化特性(开发迅速):

可以在项目中大量复用,周边生态完善(UI库,路由库),脚手架工具和项目模板省去了配置webpack时间。

三大特性:

声明式编程vs命令式编程:

命令式是用代码告诉计算机去做什么。声明式是告诉计算机想要的是什么,让计算机想出如何去做,开发者不关心如何渲染,减少操作DOM的代码量。(render什么时候运行,classname如何更新)react使用virtual dom,fiber,reconcilation。 可以与其他框架共存。

组件化:

JSX将渲染逻辑和UI逻辑结合,class继承React.Components,组件首字母大写。父组件通过属性向子组件传值和方法。子组件调用父组件传递的方法修改父组件的数据/传递数据给父组件。

一次学习,随处编写:

React DOM开发web页面,React native开发手机app,React 360开发VR界面,React electron开发PC应用,Taro开发小程序。(不同的渲染器,相同的语法)

官方脚手架CRP(Create React App)

npx create-react-app my-app npx不好用,所以这里改用了yarn create react-app my-app

Created git commit.

Success! Created react-from-zero at /Users/hdsong/WebProjects/react-from-zero
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can't go back!

We suggest that you begin by typing:

  cd react-from-zero
  yarn start

查看package.json

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

script中有四个命令,启动/打包构建/运行测试用例/暴露webpack设置 CRA把webpack设置收到了CRA的依赖中,eject暴露配置文件不可逆。 一般采用customize-cra辅助修改打包配置

"Stuff can break." --Dan Abramov

第一行代码

import React from "react";
import ReactDOM from 'react-dom';

const element = <h1>hello world !</h1>;
//在JS里面直接写HTML?,这就是JSX实际上是一个对象

ReactDOM.render(element,document.getElementById("root"));
//第一个参数是React组件或React元素,第二个参数是DOM元素作为渲染器根节点

import导入语法

这个和 ES6 没有关系,是模块系统的约定以及实现。在 node 文档里面详细描述了处理过程。 在 Node.js 模块系统中,如果 require 的模块不是核心模块,而且没有 './' 之类的开头,那就需要从当前 package 的 node_modules 里面找,找不到就到当前 package 目录上层 node_modules 里面取... 一直找到全局 node_modules 目录。 这样找到的往往是文件夹,所以接下来就是处理一个文件目录作为 Node 模块的情况。如果文件目录下有 package.json,就根据它的 main 字段找到 js 文件。如果没有 package.json,那就默认取文件夹下的 index.js。

babel默认会把ES6的模块转化为commonjs规范。

import test from 'X';
// 等价于
var test = require('X');

如果X是内置模块包括node_modules的,则直接返回该模块。如require('http')。

如果X以./、/、../开头:

根据X所在的父模块,确定X的绝对路径。 将X当做文件,依次查找下面的文件,如果找到,则直接返回。 X X.js X.json X.node 将X当做目录,依次查找下面的文件,如果找到,则直接返回。 X/package.json(查找main字段中的文件,规则同上) X/index.js X/index.json X/index.node 如果X不带路径:

根据X所在的父模块,确定X可能的安装目录。 依次在每个目录中,将X当成文件名或目录名加载。 "not found"

由于 webpack browsersify 等模块打包工具是兼容 node 的模块系统的,自然也会进行同样的处理流程。不同的是,它们支持更灵活的配置。比如在 webpack 里面,可以通过 alias 和 external 字段配置,实现对默认 import 逻辑的自定义。

编辑器调试配置

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Chrome",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}/src",
      "sourceMapPathOverrides": {
        "webpack:///src/*": "${webRoot}/*"
      }
    }
  ]
}

然后可以在VScode的调试区域看到变量和调用栈。

什么是JSX

React Element 可以嵌套,可以使用{ name }插入表达式:会返回一个值的代码单元 React元素可以不作为组件单独被渲染,是不可变对象(immutable),不能改子元素或者属性,相当于freeze冻结,不能添加新的属性。 JSX被babel(bei)编译成var element = React.createElement("h1",null,"Hello,world !");

在babeljs.io里面的Try it out可以查看JSX的真面目

JSX的出现帮助我们减少了很多代码,React库的作用,因为编译之后的代码中用到了。 React.createElement返回一个有固定数据结构的对象,type、props。

为什么使用JSX

JSX语法扩展简化代码提高效率,

”一个页面或者组件的渲染逻辑应该与其他的UI逻辑放在一起:比如事件的绑定,状态改变后渲染内容的变化。”

合并后的结果就是component组件,Jquery(模板引擎)的时候HTML和JS分离,代码被放在不同文件隔离,思考的时候需要把UI逻辑和展示逻辑分开。JSX可以用JS的思维思考整个UI逻辑,全部用JS来写。

单向数据流

父组件可以向子组件传递内容,子组件只能使用不能修改。(read only) 为了确定数据来源,方便测试定位bug。

函数式编程

易维护,函数各司其职,面向测试开发(方便自动化测试),只要看函数输出是否符合预期。