总结:React学习梳理

一、介绍

React本质上就是一个JAVASCRIPT库。

如下图,将react相关的包引入之后,就可以使用react了

React 的核心思想是:封装组件。

各个组件维护自己的状态和 UI,当状态变更,自动重新渲染整个组件。

基于这种方式的一个直观感受就是我们不再需要不厌其烦地来回查找某个 DOM 元素,然后操作 DOM 去更改 UI。

二、nodejs

参考:

总结:Nodejs

从Java的角度理解前端框架,nodejs,reactjs,angularjs区别

Node.js简介

1、介绍

nodejs就像是Java中的JVM,是js的运行环境。nodejs不是一个js框架,千万不要认为是类似jquery的框架。

nodejs的作用和jvm的一样一样的,也是js的运行环境,不管你是什么操作系统,只要安装对应版本的nodejs,那你就可以用js来开发后台程序。

node.js就是使用javascript编写,并且运行在服务器。也就是说node.js实现了使用js来开发后端

这具有划时代的意义,意味着一直以来只能在浏览器上玩来玩去的js,可以做后端开发了!

从有了nodejs后就催生出一大批用js做后台开发的前端人员,这部分人员就是偏前端的“全栈程序员”。

2、特点

使用Node.js编写的服务器采用单线程模式,即不管产生多少请求就只有一个线程,这样就可以节省内存空间,大大降低了成本。

3、React 和 Node.js的关系

React 和 Node.js 是两个不同的技术,它们的作用和功能也不同。

React 是一个用于构建用户界面的 JavaScript 库。它采用组件化的思想,可以让开发者将一个复杂的用户界面拆分成多个独立的组件,从而降低代码的复杂度,提高代码的复用性和可维护性。

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,可以用于开发服务器端应用程序。它提供了一组强大的 API,包括文件操作、网络编程、进程管理等功能,可以让开发者用 JavaScript 编写服务器端应用程序。

虽然 React 和 Node.js 是两个不同的技术,但它们可以一起使用,以构建完整的 Web 应用程序。比如,可以使用 Node.js 来搭建 Web 服务器,提供数据接口和静态资源服务,然后使用 React 来构建前端用户界面。在这种方式下,React 负责处理用户界面的展示和交互逻辑,Node.js 负责处理服务器端的业务逻辑和数据管理。

4、有了NodeJS还需要后端程序员吗?

虽然 Node.js 可以让前端开发者使用 JavaScript 编写服务器端应用程序,但它并不代表后端程序员的工作会消失。以下是一些原因:

  1. 大型应用程序需要团队协作。在大型应用程序中,通常需要多个开发者分别负责前端、后端、数据库、测试等不同的领域。后端程序员不仅负责处理服务器端的业务逻辑,还需要处理数据持久化、安全性、可扩展性等问题,需要具备专业的技术和经验。

  2. 后端技术生态系统丰富。虽然 Node.js 有着强大的生态系统和丰富的第三方库,但它并不代表其他后端技术就没有价值。其他后端技术(如 Java、Python、Ruby 等)也有着自己独特的优势和适用场景。如Flink可以做实时数据流处理,Java大型工程开发速度与各种成熟稳定框架优势,Golang协程优势,Python机器学习优势等。

  3. 不同领域的技术要求不同。虽然 Node.js 可以让前端开发者快速上手服务器端开发,但不同领域的技术要求也不同。后端程序员需要了解数据库、网络协议、服务器部署等领域的知识,才能更好地完成服务器端应用程序的开发和维护。

因此,尽管 Node.js 提供了一个新的工具和思路,但后端程序员的工作并不会因此而消失。Node.js 与其他后端技术可以一起使用,为开发者提供更多的选择和可能。

三、相关概念

React 大体包含下面这些概念:

  • 组件
  • JSX
  • Virtual DOM
  • Data Flow

这里通过一个简单的组件来快速了解这些概念,以及建立起对 React 的一个总体认识。

import React, { Component } from 'react';
import { render } from 'react-dom';

class HelloMessage extends Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

// 加载组件到 DOM 元素 mountNode
render(<HelloMessage name="John" />, mountNode);

上面的 HelloMessage 就是一个 React 构建的组件,最后一句 render 会把这个组件显示到页面上的某个元素 mountNode 里面,显示的内容就是 <div>Hello John</div>

四、组件

React 应用都是构建在组件之上。

组件有两个核心概念:

  • props
  • state

一个组件就是通过这两个属性的值在 render 方法里面生成这个组件对应的 HTML 结构。

注意:组件生成的 HTML 结构只能有一个单一的根节点。

props

props 就是组件的属性,由外部通过 JSX 属性传入设置,一旦初始设置完成,就可以认为 this.props 是不可更改的,所以不要轻易更改设置 this.props 里面的值(虽然对于一个 JS 对象你可以做任何事)。

state

state 是组件的当前状态,可以把组件简单看成一个“状态机”,根据状态 state 呈现不同的 UI 展示。

一旦状态(数据)更改,组件就会自动调用 render 重新渲染 UI,这个更改的动作会通过 this.setState 方法来触发。

五、组件的生命周期

一般来说,一个组件类由 extends Component 创建,并且提供一个 render 方法以及其他可选的生命周期函数、组件相关的事件或方法来定义。

生命周期函数

1、装载组件触发

componentWillMount

只会在装载之前调用一次,在 render 之前调用,你可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render

componentDidMount

只会在装载完成之后调用一次render之后调用,从这里开始可以通过 ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点。

2、更新组件触发

这些方法不会在首次 render 组件的周期调用

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate

3、卸载组件触发

  • componentWillUnmount

五、JSX

参考:React 使用 JSX · React入门教程

JSX 是 JavaScript 的一个语法扩展,它允许你在 JavaScript 代码中写类似 HTML 的标记。

从上面的代码可以看到将 HTML 直接嵌入了 JS 代码里面,这个就是 React 提出的一种叫 JSX 的语法

以下是 JSX 的一些关键特点:

  1. 类 HTML 的语法:JSX 允许你使用类似于 HTML 的语法来描述 UI 组件,但它实际上是 JavaScript 的一个语法扩展。

  2. 组件:JSX 常用于定义 React 组件,这些组件可以是类组件或函数组件。

  3. 表达式:在 JSX 中,你可以使用 JavaScript 表达式,例如变量、函数调用、算术运算等。

  4. 属性:你可以像在 HTML 中一样为 JSX 元素设置属性,但属性名称必须使用引号(推荐使用 JSX 规范要求的双引号)。

  5. 组件嵌套:JSX 允许你嵌套组件,这使得你能够构建复杂的 UI 布局。

  6. JavaScript 代码:在 JSX 中,你可以包含任意的 JavaScript 代码,只需使用 {} 将代码包裹起来。

  7. 转换:JSX 并不是直接运行在浏览器中的,它需要通过像 Babel 这样的编译器转换为普通的 JavaScript 代码。

以下是一些 JSX 的示例:

// 一个简单的 JSX 元素,类似于 HTML
const element = <h1>Hello, World!</h1>;

// 一个 React 组件
const MyComponent = () => {
  return <div>这是一个 React 组件</div>;
};

// 使用变量和表达式
const name = 'Alice';
const element = <p>Hello, {name}!</p>;

// 设置属性
const element = <img src="image.jpg" alt="description" />;

// 条件渲染
const element = new Date().getFullYear() >= 2020 ? <p>Happy New Year!</p> : <p>Not 2020 yet.</p>;

// 嵌套组件
const App = () => {
  return (
    <div>
      <h1>My App</h1>
      <MyComponent />
    </div>
  );
};

在 React 中,JSX 被广泛用于定义组件和 UI。它提供了一种直观的方式来描述 UI,并且与 React 的组件生命周期和状态管理紧密集成。尽管 JSX 看起来像 HTML,但它实际上是 JavaScript,因此你可以在 JSX 中使用所有的 JavaScript 特性。

利用 JSX 编写 DOM 结构,可以用原生的 HTML 标签,也可以直接像普通标签一样引用 React 组件。这两者约定通过大小写来区分,小写的字符串是 HTML 标签,大写开头的变量是 React 组件。

使用 HTML 标签:

import React from 'react';
import { render } from 'react-dom';

var myDivElement = <div className="foo" />;
render(myDivElement, document.getElementById('mountNode'));

HTML 里的 class 在 JSX 里要写成 className,因为 class 在 JS 里是保留关键字。同理某些属性比如 for 要写成 htmlFor。

使用组件:

import React from 'react';
import { render } from 'react-dom';
import MyComponent from './MyComponet';

var myElement = <MyComponent someProperty={true} />;
render(myElement, document.body);

使用 JavaScript 表达式

属性值使用表达式,只要用 {} 替换 "":

// Input (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Output (JS):
var person = React.createElement(
  Person,
  {name: window.isLoggedIn ? window.name : ''}
);

子组件也可以作为表达式使用:

// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(
  Container,
  null,
  window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);

注释

在 JSX 里使用注释也很简单,就是沿用 JavaScript,唯一要注意的是在一个组件的子元素位置使用注释要用 {} 包起来。

var content = (
  <Nav>
      {/* child comment, put {} around */}
      <Person
        /* multi
           line
           comment */
        name={window.isLoggedIn ? window.name : ''} // end of line comment
      />
  </Nav>
);

六、react中,render()的作用

在 React 中,render() 方法是一个生命周期方法,其主要作用是返回组件要渲染的内容React 通过调用每个组件的 render() 方法来确定在屏幕上显示什么。render() 方法对于理解 React 组件的工作原理至关重要。

以下是 render() 方法的一些关键点:

  1. 返回值render() 方法必须返回一个 React 元素,这可以是一个 HTML 标签(如 <div><span>)、一个自定义组件类或者 null。从 React 16.2 开始,也可以返回字符串和数字,它们会被渲染为文本节点。

  2. 性能render() 方法应该以性能为导向进行编写。避免在 render() 方法中执行重型的或不必要的操作,因为当组件的状态或属性发生变化时,render() 方法会被调用。

  3. 状态和属性render() 方法可以访问 this.propsthis.stateprops 是父组件传递给子组件的数据,而 state 是组件内部管理的数据。

  4. 生命周期:在 render() 被调用之前,组件会经历 constructor(构造函数)和 componentDidMount(对于类组件)。在之后的更新过程中,render() 会在 componentDidUpdate(更新后)之前调用。

  5. PureComponent 和 shouldComponentUpdate:如果组件继承自 React.PureComponent,则 React 会使用浅比较来比较 propsstate,如果它们没有变化,则跳过 render() 的调用。你也可以使用 shouldComponentUpdate 生命周期方法来进一步优化性能,通过返回 false 来阻止不必要的渲染。

  6. Hooks(钩子):在函数组件中,可以使用 Hooks 来使用状态和其他 React 特性,而不需要编写类组件。render() 逻辑可以包含在函数体中,并且可以使用 return 语句来返回要渲染的元素。

  7. 渲染到 DOM:React 调用 render() 方法后,会生成一个 React 元素树,然后使用虚拟 DOM 技术高效地更新实际的 DOM。

  8. 无副作用:理想情况下,render() 方法应该是无副作用的,这意味着它不修改组件的状态或触发任何异步操作。所有副作用应该放在 useEffect(对于函数组件)或 componentDidMountcomponentDidUpdate(对于类组件)等生命周期方法中。

下面是一个简单的类组件示例,展示了 render() 方法的用法:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    // 访问属性和状态
    const { someProp } = this.props;
    const { count } = this.state;

    return (
      <div>
        <h1>{someProp} {count}</h1>
        {/* 其他 JSX 元素 */}
      </div>
    );
  }
}

在如下函数组件中,render() 方法的概念被组件的返回语句所取代:

function MyComponent({ someProp }) {
  // 使用 Hooks 管理状态
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h1>{someProp} {count}</h1>
      {/* 其他 JSX 元素 */}
    </div>
  );
}

在两种情况下,组件最终都返回 JSX,React 会将其转换为浏览器中的实际 DOM 元素。

七、DOM

DOM(文档对象模型,Document Object Model)是 HTML 和 XML 文档的编程接口。它提供了一种方式,使得开发者能够使用编程语言(如 JavaScript)来动态地访问和更新数据,以及操作网页内容和结构。

DOM 将网页表示为一个由节点构成的树状结构,每个节点代表文档中的一个元素或片段。这个树状结构的每个节点都是一个特定的对象,拥有属性和方法。

以下是 DOM 的一些关键概念:

  1. 节点(Node):DOM 树中的一个元素,可以是文档本身,一个元素,文本,或者是一个注释。

  2. 元素(Element):表示 HTML 中的一个标签,如 <div>, <p>, <span> 等。

  3. 属性(Attribute):与 HTML 元素相关的信息,如 class, id, src 等。

  4. 文本(Text):元素内的文本内容。

  5. 文档(Document):整个 HTML 或 XML 文档的根节点。

  6. 选择器(Selectors):用于查找和访问 DOM 元素的方法,如 getElementById, getElementsByClassName, querySelector 等。

  7. DOM API:一组方法和属性,允许开发者访问和操作 DOM 树。

以下是一些 DOM 元素的例子:

  1. HTML 文档的根元素(<html>)是 DOM 树的根节点。

  2. <body> 元素是文档的主体,包含网页的所有内容。

  3. <div id="main"> 是一个带有 id 属性的 div 元素。

  4. <a href="https://example.com">Link</a> 是一个带有 href 属性的超链接。

  5. <img src="image.jpg" alt="description"> 是一个图像元素,包含 srcalt 属性。

  6. <span class="highlight">Text</span> 是一个带有文本内容的 span 元素,并且有一个 class 属性。

  7. <input type="text" name="username"> 是一个文本输入框元素,包含 typename 属性。

  8. <ul><li>Item 1</li><li>Item 2</li></ul> 表示一个无序列表,包含两个列表项。

在 JavaScript 中,你可以使用 DOM API 来操作这些元素,例如:

// 通过 id 获取元素
var mainDiv = document.getElementById('main');

// 通过类名获取元素集合
var items = document.getElementsByClassName('highlight');

// 通过标签名获取元素集合
var links = document.getElementsByTagName('a');

// 创建新元素
var newElement = document.createElement('p');

// 设置元素的文本内容
newElement.textContent = 'New paragraph';

// 设置元素的属性
newElement.setAttribute('class', 'new-class');

// 将新元素添加到文档中
mainDiv.appendChild(newElement);

通过这些操作,开发者可以动态地修改网页的外观和行为,而无需重新加载页面。

Virtual DOM

当组件状态 state 有更改的时候,React 会自动调用组件的 render 方法重新渲染整个组件的 UI。

当然如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个Virtual DOM,组件 DOM 结构就是映射到这个 Virtual DOM 上,React 在这个 Virtual DOM 上实现了一个 diff 算法,当要重新渲染组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的 DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个 Virtual DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多。

八、redux

1、介绍

在react中,组件与组件进行数据交互时,我们可以用this.props在不同组件之间传递数据,但是当开发一个大型应用时,用this.props将数据一层一层的传下去来进行组件之间的通信就会变得非常的麻烦,这个时候,redux应运而生,redux就是用来解决开发庞大应用时的数据交互问题。

2、reducer 

reducer是一个函数,它接受2个参数,一个是state,一个是action,然后根据action的内容对state作出修改,并返回一个新的state,下面是一个例子:

注意:

1、参数state有一个默认值,这个默认值会作为state的初始值

2、reducer函数不用直接使用,它会在dispatch函数中调用。

3、action

我们是不能直接操作state的,我们只能接触到view,action就是操作view后,view发出的通知,告诉state要改变了,具体怎么改变取决于action的内容。

action是一个对象,它必须要含有一个type属性,用来区别不同类型的action,下面是一个action的例子:

其他的属性可以根据自己的需要来定义。

八、dva

项目中存在:import { browserHistory, hashHistory } from 'dva/router';

看不懂,来研究下dva是啥。

1、介绍

基于 React 和 Redux 的树型结构轻量级 JS 框架。

2、特点

  • 基于 redux、redux-saga 和 react-router:站在巨人的肩膀上。

  • small api:仅 5 个 api 方法,很容易学习。

  • elm cocepts:基于 reducers、effects 和 subscriptions 的组织模型。

  • 支持 mobile 和 react-native:跨平台。

  • 动态 model 和 router:拆分大型应用程序和负载的需求。

3、dva的几个规则

1、通过dispatch调用namespace/effects

2、effects (异步操作)

  • 函数必须带*,也就是生成器。
  • 第一个参数,可以拓展为{payload, callback}
  • 第二个参数,call和put
    • call 就是调用 async的action函数
    • put就是调用reducers的函数来更新state。

4、开发

准备阶段:

  • 定义 state 状态,用以绑定到 view 层;
  • 定义 effects
    • call用来调用 action,类似dispatch
    • put用来调用reducers
  • 定义 sync action 函数,用来进行异步请求;
  • 定义 reducers 函数,用来更新 state。

调用阶段:

拿到dispatch

const { dispatch } = this.props

dispatch({type: 'count/add'}) // this.props.dispatch({type: 'count/add'})

可以直接调用 effects, 也可以直接调用reducers。如果是同名的话,会一起调用。优先执行reducers。

5、yield

自带的固定关键词,和"*"搭配使用。有点像async和await,使用"*"则表明它是Generator函数,然后每使用一个"yield"就是告诉程序这里是异步,需要等待这个后面的代码执行完成。同步代码可不使用该关键词

6、payload

view端通过dispatch传过来的payload同名参数

7、select, call, put

dva中effects函数的固定传参,他们分别对应不同的功能,用于不用场景

select

拿到model中state的数据。

即用于从 Redux store 中获取 state 中的某个属性的值。

const list = yield select((s) => s.commodity.list);

 call

第一个参数是一个异步函数,payload是参数,可以通过call来执行一个完整的异步请求,又因为yield的存在,就实现了异步转同步的方案

const res = yield call(pageQuery, payload)

put

可以使用同model中的reducers或者effects,通过reducers来实现数据到页面的更新。可以通过put实现effect的嵌套使用

yield put({
       type: 'save',
       payload: {
         detail: res.result,
       },
});

九、Webpack 配置 React 开发环境

Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能。

假设我们在当前工程目录有一个入口文件 entry.js,React 组件放置在一个 components/ 目录下,组件被 entry.js 引用,要使用 entry.js,我们把这个文件指定输出到 dist/bundle.js,Webpack 配置如下:

var path = require('path');

module.exports = {
    entry: './entry.js',
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    module: {
        loaders: [
            { test: /\.js|jsx$/, loaders: ['babel'] }
        ]
    }
}

resolve 指定可以被 import 的文件后缀。比如 Hello.jsx 这样的文件就可以直接用 import Hello from 'Hello' 引用。

loaders 指定 babel-loader 编译后缀名为 .js 或者 .jsx 的文件,这样你就可以在这两种类型的文件中自由使用 JSX 和 ES6 了。

监听编译: webpack -d --watch

十、react 之 web存储 localStorage

在 Html5 中新加入的 localStorage 特性,主要是用来作为本地存储使用的,解决了cookie 存储空间不足的问题
cookie 中每条 cookie 的存储空间为 4K, localStorage 中一般浏览器支持的是 5M大小,在不同浏览器中 localStorage 会有所不同。

localStorage 与 sessionStorage 的唯一区别就是 localStorage 属于永久性存储,而sessionStorage 属于当会话结束的时候,sessionStorage 中的键值对就会被清空。

---------------- 存:将数据存储到localStorage ----------------
localStorage.setItem("phone", "123")

//对象
let obj = {"name":"xiaoming","age":"16"}
localStorage.setItem("phone",JSON.stringify(obj));

---------------- 取:从localStorage中取出 ----------------
localStorage.getItem("phone")

//对象
let user = JSON.parse(localStorage.getItem("phone"))

---------------- 删除 ----------------
//指定删
localStorage.removeItem('phone');

//全删
localStorage.clear(); 

-------- 设置localStorageSet 过期时间 --------
const localStorageSet = (name, data) => {
    const obj = {
        data,
        expire: new Date().getTime() + 1000 * 60 * 30
    };
    localStorage.setItem(name, JSON.stringify(obj));
};

---------------- 读取缓存 ----------------
const localStorageGet = name => {
    const storage = localStorage.getItem(name);
    const time = new Date().getTime();
    let result = null;
    if (storage) {
        const obj = JSON.parse(storage);
        if (time < obj.expire) {
            result = obj.data;
        } else {
            localStorage.removeItem(name);
        }
    }
    return result;
};

---------------- 使用 ----------------
//存
localStorageSet('weather', data)

//取(返回null则过期)
localStorageGet('weather')

十一、export

1、export介绍

在JavaScript中,export语句用于将一个模块中的函数、类、变量或常量等对象导出,从而可以在其他模块中使用这些对象

export default语句则是export语句的一种特殊形式,它用于导出默认的对象。每个模块中只能有一个默认导出的对象,而且不需要使用花括号{}来引入这个对象

例如,以下是一个简单的模块文件math.js,其中包含了一个默认导出的函数:

function add(x, y) {
  return x + y;
}

export default add;

在其他模块中,可以通过以下方式导入这个模块并使用默认导出的函数:

注意:以下第一行的import没有使用{}

在这个例子中,使用import语句将math.js模块导入,使用了默认的导出

import add from './math.js';

const result = add(2, 3);
console.log(result); // Output: 5

除了默认导出对象,还可以使用export语句将多个函数、类、变量或常量等对象导出到其他模块中。在导入这些非默认导出对象时,需要使用花括号{}来指定要导入的对象的名称。

例如,以下是一个包含两个函数的模块文件:

export function add(x, y) {
  return x + y;
}

export function subtract(x, y) {
  return x - y;
}

在其他模块中,可以通过以下方式导入这个模块并使用其中的函数:

注意:第一行的import语句中,add是用{}的,而导入默认的

import { add, subtract } from './math.js';

const result1 = add(2, 3);
console.log(result1); // Output: 5

const result2 = subtract(5, 2);
console.log(result2); // Output: 3

2、export default {}和export default 函数有什么区别?

在JavaScript中,export default有两种用法,分别是导出一个默认的对象和导出一个默认的函数

export default {}:用于导出一个默认的空对象,它不包含任何属性或方法。这个对象可以在其他模块中使用import语句导入,然后通过点号(.)访问其属性或方法。例如:

// module1.js
export default {};

// module2.js
import myObj from './module1.js';
myObj.myProp = 'Hello, world!';
console.log(myObj.myProp); // Output: Hello, world!

在这个例子中,module1.js模块导出了一个空对象{}。在module2.js模块中,使用import语句将这个对象导入,并添加了一个属性myProp。然后使用console.log语句输出了这个属性的值。

export default 函数:用于导出一个默认的函数,这个函数可以在其他模块中使用import语句导入,并像普通函数一样调用。例如:

// module1.js
export default function add(x, y) {
  return x + y;
}

// module2.js
import add from './module1.js';
const result = add(2, 3);
console.log(result); // Output: 5

在这个例子中,module1.js模块导出了一个名为add的函数。在module2.js模块中,使用import语句将这个函数导入,并使用它执行了加法运算,并将结果输出到控制台。

因此,export default {}和export default 函数的区别在于,它们导出的对象的类型不同,一个是空对象,一个是函数。在使用import语句导入时,也需要使用不同的语法来引用这些默认导出的对象。

十二、connect函数

在看前端项目的时候遇到了代码段:export default connect(({ faultNoticeSservice,host,loading }) => ({ faultNoticeSservice,host, loading }))(FaultNoticeSservice);

不明白作用,搜了下,解释如下。

这段代码使用了connect函数将React组件FaultNoticeSservice连接到Redux Store上,使得该组件可以访问全局状态对象(state)中的数据并更新它们

在代码中,connet函数接受全局状态对象中的三个属性:faultNoticeSservicehostloading。这个函数返回的对象中也有这三个属性,它们的值就是从全局状态对象中取出的值。因此,当组件FaultNoticeSservice被渲染时,它可以通过props属性访问这三个属性,以及它们所对应的全局状态对象中的数据

最终,这个函数返回的对象会被作为props属性传递给组件FaultNoticeSservice。这意味着,组件中的任何地方都可以使用这些属性,从而访问全局状态对象中的数据。

总的来说,这段代码的作用是将组件FaultNoticeSservice连接到Redux Store上,以使得该组件可以访问全局状态对象并更新它们。

kimi:

export default connect()(MyComponent);

在 React 应用中,export default connect()(MyComponent); 是使用 React-Redux 库将 Redux 的 store 与 React 组件连接的一种方式。这行代码的作用是将 Redux 的 dispatch 方法和其他可能的状态(state)映射到 React 组件的 props 中。

让我们分解这行代码:

  1. connect():

    • 这是 React-Redux 提供的一个函数,它接收两个可选的参数:mapStateToProps 和 mapDispatchToProps。这两个参数分别用于将 Redux store 的状态映射到组件的 props(通过 mapStateToProps),以及将 dispatch 方法映射到组件的 props(通过 mapDispatchToProps)。
  2. MyComponent:

    • 这是你要连接到 Redux store 的 React 组件。
  3. connect()(MyComponent):

    • 当你调用 connect() 并传入组件 MyComponent 时,React-Redux 返回一个新的组件,这个组件通过 Redux 与 store 连接。返回的组件可以访问到由 mapStateToProps 和 mapDispatchToProps 映射过来的 props
  4. export default:

    • 这是 JavaScript ES6 的语法,用于导出模块的默认成员。在这里,它将通过 connect() 创建的连接了 Redux store 的新组件作为模块的默认导出。

当你不向 connect() 传递任何参数,如 connect()(MyComponent) 时,它将组件转换为一个可以访问整个 Redux store state 和 dispatch 方法的组件,但不会自动映射任何特定的状态或 action creator 到组件的 props。这样做的结果是一个“容器组件”,它在内部管理与 Redux store 的连接,而原始的 MyComponent 则保持为一个纯组件(也称为“展示组件”或“笨组件”)。

例如,如果你有如下的 MyComponent

const MyComponent = ({ data, onButtonClick }) => { // 使用 data 和 onButtonClick 渲染 UI };

在使用 connect() 之后,MyComponent 将能够通过其 props 访问整个 Redux store 的状态和分派 actions 的能力,但具体能访问哪些状态和actions取决于你在 mapStateToPropsmapDispatchToProps 中如何配置。

在 React-Redux v7.1.0+ 中,connect() 也支持更简洁的用法,允许你省略第一个参数,如下所示:

export default connect()(MyComponent);

这与传递一个返回空对象的 mapStateToProps 参数的效果相同,意味着组件不会从 Redux store 的状态中接收任何 props,但仍然可以分派 actions。如果你需要分派 actions 但不关心 Redux store 的状态,这种方式很有用。

十三、案例

解释下:export default connect(({ subscribeForm, templatesModel, loading }) => ({ subscribeForm, templatesModel, loading }))(Subscribe)

这段代码是使用 React-Redux 的 connect 函数来连接 Redux store 和 React 组件的示例。在这个例子中,Subscribe 是一个 React 组件,而 connect 函数用于将 Redux store 中的状态(state)和 action creators 映射到 Subscribe 组件的 props 中。

让我们逐步分析代码:

  1. connect 函数的第一个参数是一个对象,它定义了如何将 Redux store 中的状态映射到组件的 props。在这个例子中,我们选择了 subscribeFormtemplatesModelloading 三个部分的状态:

    ({ subscribeForm, templatesModel, loading })

    这意味着 connect 函数将从 Redux store 中提取 subscribeFormtemplatesModelloading,并将它们作为 props 传递给 Subscribe 组件。

  2. connect 函数的返回值是一个新函数,这个新函数接收一个 React 组件,并返回一个新的 React 组件。这个新的组件被包装(wrap),并且拥有与 Redux store 相关联的额外功能。

  3. connect(({ subscribeForm, templatesModel, loading }) => ({ subscribeForm, templatesModel, loading })) 这部分调用 connect 并传入上面提到的映射函数。映射函数简单地将所选的状态返回为一个对象,这意味着 Subscribe 组件的 props 将直接包含 subscribeFormtemplatesModelloading

  4. (Subscribe) 这里将原始的 Subscribe 组件传递给 connect 返回的高阶函数(HOC),从而创建一个新的组件。这个新组件将具有从 Redux store 映射过来的 props

  5. export default 将由 connect 创建的连接了 Redux 的新组件导出为默认导出。这意味着你可以在其他文件中通过默认导入的方式使用这个组件,并能够访问到 Redux store 中的状态和 action creators。

最终,这段代码的作用是创建一个 Redux 连接的 React 组件,它使得 Subscribe 组件能够访问到 Redux store 中的 subscribeFormtemplatesModelloading 部分的状态。这样做可以方便地在组件内部使用这些状态,以及分派 action 来更新 Redux store。

在 React-Redux v7.1.0+ 中,connect 函数的使用变得更加简洁,允许你省略 mapDispatchToProps 参数,如果 action creators 需要 dispatch,可以作为参数传递给 action creators。以下是使用 v7.1.0+ 版本的 connect 的示例:

export default connect(
  ({ subscribeForm, templatesModel, loading }) => ({
    subscribeForm,
    templatesModel,
    loading
  })
)(Subscribe);

在这个例子中,connect 的第一个参数是一个函数,它接收整个 Redux store 的状态作为参数,并返回一个对象,对象中的属性将作为 props 传递给 Subscribe 组件。

另外,上面提到的subscribeForm,就是已经注册到了Redux store 中,所以才有了上面的export default connect(({ subscribeForm, templatesModel, loading }) => ({ subscribeForm, templatesModel, loading }))(Subscribe),将subscribeForm通过connect 函数将Redux store 中提取的 subscribeFormtemplatesModelloading,作为 props 传递给 Subscribe 组件。

import * as services from '../services/subscribe';
import { message } from 'antd';
import { hashHistory } from 'dva/router';

export default {

  namespace: 'subscribeForm',

  state: {
    tagValueSelect: [],
    informValue:[],
    subscribeList: {}
  }
}

十四、this.props.dispatch()

this.props.dispatch() 是 React-Redux 库中提供的一个函数,用于在组件中派发一个 action,触发对应的 reducer 去更新 state,从而更新 React 组件的 UI 界面。

this.props 是 React 组件中的属性,它包含了一些传递给组件的属性或者组件的状态。

dispatch 属性是 connect 函数通过 Redux Store 提供的,并通过 props 传递给组件,通过它可以派发一个 action

当你执行 this.props.dispatch({}) 时,你实际上是在派发一个 action 到 Redux Store 中。这个 action 是一个 JavaScript 对象,它描述了要进行的操作,并包含了必要的数据。根据这个 action,Redux Store 将会调用相应的 reducer 去更新 state,并且通知所有已经订阅了 store 的组件去更新它们的 UI。

因此,this.props.dispatch({}) 的作用就是在组件中触发一个 action,从而更新 Redux Store 中的 state,并通知所有的订阅组件去更新它们的 UI。

十五、Redux Store是什么?

1、介绍

Redux Store 是 Redux 应用程序中的核心概念,它是一个包含应用程序状态的 JavaScript 对象,同时也是唯一能够修改这个状态的地方。它的主要作用是:

  1. 存储应用程序的状态,即数据。
  2. 处理状态的更新。Redux Store 只能通过 dispatch() 方法中派发一个 action 去更新状态,Reducer 函数会接收到这个 action,并返回一个新的状态,Store 会将这个新的状态保存下来,从而更新整个应用程序的 UI 界面。
  3. 提供状态访问的方法。通过 getState() 方法,可以获取当前应用程序状态的快照,以便在需要时使用。

Redux Store 是一个单一的 JavaScript 对象,它的状态是不可变的。要更新状态,必须通过派发一个 action 去更新。

同时,Redux Store 也是应用程序中数据流的中心,可以通过在组件中使用 connect() 方法连接 Redux Store,将状态作为属性注入到组件中,从而更新组件的 UI 界面。

2、和React的关系

Redux Store 和 React 组件是相互独立的,它们之间没有任何关系。Redux Store 可以在任何 JavaScript 应用程序中使用,包括 React 应用程序。而 React 组件可以使用任何状态管理库来管理组件状态,包括 Redux Store。所以说,Redux Store 和 React 之间并没有直接的关系,它们只是为了更好地组织和管理应用程序状态而存在。

十五、TextArea使用

在 React 中,TextArea 组件需要从 antd 库中导入,你需要在代码中引入 TextArea 组件,然后才能使用它。例如,你可以在代码中这样导入 TextArea

import { Input } from 'antd';

const { TextArea } = Input;

// 然后就可以在 render 方法中使用 TextArea 了
render() {
  return (
    <div>
      <TextArea />
    </div>
  );
}

在这个例子中,我们通过 import { Input } from 'antd'; 语句导入了 antd 库中的 Input 组件,然后通过 const { TextArea } = Input; 语句将 Input 中的 TextArea 组件解构出来,然后就可以在 render 方法中使用 TextArea 组件了。

十六、项目中的package-lock.json,package.json,yarn.lock三个文件是什么关系?

"package-lock.json"、"package.json"和"yarn.lock"这三个文件都是用于管理项目依赖项的文件,它们之间有着一定的关系。

"package.json"是一个必须存在于每个Node.js项目根目录的JSON格式文件。它描述了项目的各种信息,包括项目名称、版本、许可证、作者、依赖项等等。其中,"dependencies"和"devDependencies"属性列出了项目所需的所有依赖项。

"package-lock.json"是由npm在安装任何依赖项时自动生成的文件,它记录了项目依赖项的确切版本以及依赖项之间的依赖关系。它的作用是确保项目的依赖项在不同的机器和环境之间的一致性。

"yarn.lock"是由Yarn在安装任何依赖项时自动生成的文件,它的作用与"package-lock.json"相似,也是记录项目依赖项的确切版本和依赖项之间的依赖关系。

当使用npm或Yarn安装或更新项目的依赖项时,它们会自动更新"package-lock.json"或"yarn.lock"文件,以反映新的依赖项版本和依赖关系。这确保了在不同机器和环境中的依赖项保持一致。

总的来说,"package.json"文件是描述项目信息和依赖项的清单文件,"package-lock.json"和"yarn.lock"文件则是确保依赖项版本控制和一致性的重要工具。它们三者之间的关系是,"package-lock.json"和"yarn.lock"文件都记录了项目的依赖项版本和依赖关系,而"package.json"则是依赖项清单的总览。

问:package-lock.json可以手动修改吗?

答:虽然可以手动编辑"package-lock.json"文件,但不建议这样做。这是因为"package-lock.json"文件是由npm自动生成和维护的,手动编辑文件可能会导致依赖项版本的不一致或不正确,从而导致不可预测的行为或错误。

如果确实需要更改"package-lock.json"文件,可以使用npm命令行工具提供的"npm update"命令或手动删除"package-lock.json"文件并重新运行"npm install"来更新依赖项版本和依赖关系。这样做可以确保依赖项版本的正确性和一致性,并避免不必要的问题。

总的来说,最好避免手动编辑"package-lock.json"文件,而是依靠npm自动生成和维护的方式来管理项目的依赖项。如果需要更新依赖项版本,可以使用相应的命令行工具,如"npm update"或"yarn upgrade"来实现。

相关文档:

React 中文文档 · React入门教程

开始 – React

从Java的角度理解前端框架,nodejs,reactjs,angularjs,requirejs,seajs_uikoo9的博客-CSDN博客_node.js react 区别

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React前端和Node.js后端之间使用WebSocket连接的方法如下: 1在Node.js服务器端安装websocket库: ```bash npm install websocket ``` 2.在Node.js服务器端创建WebSocket服务器: ```javascript const WebSocket = require('websocket').server; const http = require('http'); const server = http.createServer(function(request, response) { // 处理HTTP请求 }); server.listen(8080, function() { console.log((new Date()) + ' Server is listening on port 8080'); }); wsServer = new WebSocket({ httpServer: server }); // 处理WebSocket连接 wsServer.on('request', function(request) { const connection = request.accept(null, request.origin); console.log('WebSocket connection accepted.'); // 处理WebSocket消息 connection.on('message', function(message) { if (message.type === 'utf8') { console.log('Received Message: ' + message.utf8Data); connection.sendUTF('Hi this is WebSocket server!'); } }); // 处理WebSocket关闭 connection.on('close', function(reasonCode, description) { console.log('WebSocket connection closed.'); }); }); ``` 在此示例中,我们使用了Node.js的HTTP模块和WebSocket库。我们创建了一个HTTP服务器,并将WebSocket服务器绑定到该服务器上。当收到WebSocket连接请求时,我们将打印一条消息,当接收到WebSocket消息时,我们将回复一个消息。当WebSocket连接关闭时,我们将打印一条消息。 3.在React前端中使用WebSocket连接: ```javascript import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; import WebSocket from 'websocket'; class App extends Component { constructor(props) { super(props); this.state = { message: '', ws: null }; } componentDidMount() { // 创建WebSocket连接 const ws = new WebSocket('ws://localhost:8080'); ws.onopen = () => { console.log('WebSocket Client Connected'); }; ws.onmessage = (message) => { console.log('Received:', message.data); this.setState({ message: message.data }); }; ws.onclose = () => { console.log('WebSocket closed'); }; this.setState({ ws }); } render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </header> <p className="App-intro"> {this.state.message} </p> </div> ); } } export default App; ``` 在React前端中,我们使用了WebSocket库来创建WebSocket连接。我们使用`componentDidMount`方法在组件挂载后创建WebSocket连接。当WebSocket连接打开时,我们将打印一条消息,当接收到WebSocket消息时,我们将更新组件状态以显示该消息。当WebSocket连接关闭时,我们将打印一条消息。 在React前端中,我们只需要提供WebSocket服务器的URL,即可建立WebSocket连接。在此示例中,我们将WebSocket服务器的URL设置为`ws://localhost:8080`,因为我们假设Node.js服务器运行在本地8080端口上。 以上是React前端和Node.js后端之间使用WebSocket连接的基本步骤,你可以根据自己的实际需求进行进一步的开发和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值