react实践

React 最佳实践一、 React 与 AJAX
React 只负责处理 View 这一层,它本身不涉及网络请求 /AJAX:

第一,用什么技术从服务端获取数据;
第二,获取到的数据应该放在 react 组件的什么位置。

事实上是有很多的:fetch()、fetch polyfill、axios...
其中最需要我们关注的是window.fetch(),它是一个简洁、标准化的 javascript 的 Ajax API 。
在 Chrome 和 Firefox 中已经可以使用,如果需要兼容其他浏览器,可以使用 fetch polyfill 。
ajax实践:

1.所有的数据请求和管理都存放在唯一的一个根组件让父组件 /根组件集中发送所有的 ajax 请求,
把从服务端获取的数据统一存放在这个组件的 state 中,再通过 props 把数据传给子组件。
这种方法主要是针对组件树不是很复杂的小型应用。缺点就是当组件树的层级变多了以后,
需要把数据一层一层地传给子组件,写起来麻烦,性能也不好。2.设置多个容器组件专门处理数据请求和管理其实跟第一种方法类似,只不过设置多个容器组件来负责数据请求和状态管理。
这里我们需要区分两种不同类型的组件,
一种是展示性组件( presentational component ),
另一种是容器性组件( container component )。
展示性组件本身不拥有任何状态,所有的数据都从容器组件中获得,在容器组件中发送 ajax 请求。3.使用 Redux 或 Relay 的情况Redux 管理状态和数据, Ajax 从服务器端获取数据,所以很显然当我们使用了 Redux 时,
应该把所有的网络请求都交给 redux 来解决。具体来说,应该是放在Async Actions。
如果用其他类 Flux 库的话,解决方式都差不多,都是在 actions 中发送网络请求。

把计算和条件判断都交给render()方法吧

echarts
概览页面 -》 echats图修改的时候犯了个错 yield put({ type: ' DescribeInvadeTrend' }); --》
发现没有请求 咋回事!!!! 注意观察代码...

React setState
setState(updater, callback)这个方法是用来告诉react组件数据有更新,有可能需要重新渲染。它是异步的,react通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能,所以这就给我们埋了一个坑:
那就是在使用setState改变状态之后,立刻通过this.state去拿最新的状态往往是拿不到的。
所以第一个使用要点就是:如果你需要基于最新的state做业务的话,可以在componentDidUpdate或者setState的回调函数里获取。(注:官方推荐第一种做法)
设想有一个需求,需要在在onClick里累加两次,如下:

onClick = () => {this.setState({ index: this.state.index + 1 });this.setState({ index: this.state.index + 1 });}

在react眼中,这个方法最终会变成

Object.assign(previousState,{index: state.index+ 1},{index: state.index+ 1},...
)

由于后面的数据会覆盖前面的更改,所以最终只加了一次.所以如果是下一个state依赖前一个state的话,推荐给setState传function

onClick = () => {this.setState((prevState, props) => {return {quantity: prevState.quantity + 1};});this.setState((prevState, props) => {return {quantity: prevState.quantity + 1};});
}

以上是使用setState的两个注意事项,接下来我们来看看setState被调用之后,更新组件的过程:

ReactBaseClassses.js
ReactComponent.prototype.setState = function (partialState, callback) {//  将setState事务放进队列中this.updater.enqueueSetState(this, partialState);if (callback) {this.updater.enqueueCallback(this, callback, 'setState');}
};

这里的partialState可以传object,也可以传function,它会产生新的state以一种Object.assgine()的方式跟旧的state进行合并。

二、enqueueSetState

enqueueSetState: function (publicInstance, partialState) {// 获取当前组件的instancevar internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');// 将要更新的state放入一个数组里var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);queue.push(partialState);//  将要更新的component instance也放在一个队列里enqueueUpdate(internalInstance);}
.

..消化...

state和props
React 的核心思想是组件化的思想,而React 组件的定义可以通过下面的公式描述:
UI = Component(props, state)
不是对props 和state 基本用法的介绍,而是尝试从更深层次解释props 和 state,并且归纳使用它们时的注意事项。
一句话概括,props 是组件对外的接口,state 是组件对内的接口。
组件的props 和 state都和组件最终渲染出的UI直接相关。
组件中用到的一个变量是不是应该作为组件state,可以通过下面的4条依据进行判断:

  1. 这个变量是否是通过props从父组件中获取?如果是,那么它不是一个状态。

  2. 这个变量是否在组件的整个生命周期中都保持不变?如果是,那么它不是一个状态。

  3. 这个变量是否可以通过state 或props 中的已有数据计算得到?如果是,那么它不是一个状态。

  4. 这个变量是否在组件的render方法中使用?如果不是,那么它不是一个状态。这种情况下,这个变量更适合定义为组件的一个普通属性(除了props 和 state以外的组件属性 ),例如组件中用到的定时器,就应该直接定义为this.timer,而不是this.state.timer。

    不能依赖当前的props计算下个state,因为props的更新也是异步的。
Object.assign(previousState,{quantity: this.state.quantity + 1},{quantity: this.state.quantity + 1}
)

当点击一次购买按钮,购买的数量就会加1,如果我们连续点击了两次按钮,就会连续调用两次this.setState({quantity: this.state.quantity + 1})

// 正确
this.setState((preState, props) => ({counter: preState.quantity + 1; 
}))

State 的更新是一个浅合并(Shallow Merge)的过程。
例如,一个组件的state为:

this.state = {title : 'React',content : 'React is an wonderful JS library!'
}
this.setState({title: 'Reactjs'});
React会合并新的title到原来的组件state中,同时保留原有的状态content,合并后的state为:
{title : 'Reactjs',content : 'React is an wonderful JS library!'
}

State与Immutable
React官方建议把state当作不可变对象,一方面是如果直接修改this.state,组件并不会重新render;另一方面state中包含的所有状态都应该是不可变对象。
如有一个数组类型的状态books,当向books中增加一本书时,使用数组的concat方法或ES6的数组扩展语法(spread syntax):

// 方法一:使用preState、concat创建新数组
this.setState(preState => ({books: preState.books.concat(['React Guide']);
}))// 方法二:ES6 spread syntax
this.setState(preState => ({books: [...preState.books, 'React Guide'];
}))
当从books中截取部分元素作为新状态时,使用数组的slice方法:
// 使用preState、slice创建新数组
this.setState(preState => ({books: preState.books.slice(1,3);
}))

当从books中过滤部分元素后,作为新状态时,使用数组的filter方法:

this.setState(preState => ({books: preState.books.filter(item => {return item != 'React'; });
}))

注意不要使用push、pop、shift、unshift、splice等方法修改数组类型的状态,因为这些方法都是在原数组的基础上修改,而concat、slice、filter会返回一个新的数组。

状态的类型是简单对象(Plain Object)

this.state = {owner = {name: '老干部',age: 30}  
}
this.setState(preState => ({owner: Object.assign({}, preState.owner, {name: 'Jason'});
}))
//第一种方法
this.setState(preState => ({owner: {...preState.owner, name: 'Jason'};
}))
//第二种方法

总结一下,创建新的状态的关键是,避免使用会直接修改原对象的方法,而是使用可以返回一个新对象的方法。当然,也可以使用一些Immutable的JS库,如Immutable.js,实现类似的效果。
那么,为什么React推荐组件的状态是不可变对象呢?一方面是因为不可变对象方便管理和调试,了解更多可参考这里: http://redux.js.org/docs/faq/ImmutableData.html#benefits-of-immutability
另一方面是出于性能考虑,当组件状态都是不可变对象时,我们在组件的shouldComponentUpdate方法中,仅需要比较状态的引用就可以判断状态是否真的改变,从而避免不必要的render方法的调用。当我们使用React 提供的PureComponent时,更是要保证组件状态是不可变对象,否则在组件的shouldComponentUpdate方法中,状态比较就可能出现错误。
porps的改变为什么是异步的? ????????

React顶级API

React.Component
class Greeting extends React.Component {render() {return <h1>Hello, {this.props.name}</h1>}
}
ReactDOM.render(<Greeting name={"zhangyatao"}/>,document.getElementById('root)
)

React.PureComponet
它实现了shouldComponentUpdate()对props和state的进行浅比较。
React.PureComponent的shouldComponentUpdate()仅会对对象进行浅比较,如果对象包含复杂的数据结构,对于深层次的差异有可能会产生false-negatives(假阴性,相当于医院中的错诊)。

React.Children
React.children提供了处理this.props.children中那些不透明的数据结构的一些工具函数。

React.Children.map
React.Children.map(children, function[(thisArg))
React.Children.forEach(children, function[(thisArg)])
和React.Children.map相同,只不过不会返回一个数组。

React.Children.count
React.Children.count(children)
返回children中的组件总数。

React.Children.toArray
React.Children.toArray(children)
将子元素中的不透明数据结构作为一个一维数组返回。如果你想在render方法中操作children集合,特别是如果你想在传递它之前重新排序或切割this.props.children,这个方法将非常有用。

React.PropTypes
React.PropTypes是一系列类型验证器的集合,可以与组件的propTypes对象一起使用,以验证传递到组件的props。

深入理解JSX
从根本上讲,JSX就是提供了一个React.createElement(component, props, ...children)函数的语法糖。就像下面的JSX代码:

<MyButton color="blue" shadow={2}>Click Me
</MyButton>

经过编译后为:

React.createElement(MyButton,{color: 'blue', shadow: 2},'Click Me'
)
<div className="sidebar" />

经过编译后为:

React.createElement('div',{className: 'sidebar'},null
)

如果你想测试一些特定的JSX是如何转换成JavaScript的话,你可以试试在线Babel编译器。
由于JSX编译的本质是对React.createElement的调用,因此React库也必须始终在JSX代码的作用域中。
还可以使用JSX中的点表示符来引用React组件

const MyComponents = {DatePicker(props) {return <div>这里有一个颜色为{props.color}的日期选择器</div>}
};function BlueDataPicker(props) {return <MyComponents.DatePicker color="blue" />
}

字符串直接量

<MyComponent message="hi " /><MyComponent message={'hi'} />
<MyComponent message='&lt;3' /><MyComponent message={'<3'} />

Props传递
如果你有一个对象类似的数据作为props,并且想在JSX中传递它,你可以使用...作为一个“spread”运算符传递整个props对象。 这两个组件是等效的:

function App() {return <Greeting firstName="yatao" lastName="zhang" />;
}function App() {const props = {firstName: 'yatao', lastName: 'zhang'};return <Greeting {...props} />;
}

JSX中的子元素和子组件

function MyComponent(props) {return <div>{props.children}<div>; //=> <div>hello</div>
}

JSX会删除行的开始和结尾处的空格。 它也会删除中间的空行。 与标签相邻的空行被会被删除;
在字符串文本中间出现的空行会缩合成一个空格。 所以这些都渲染相同的事情:布尔值、null、undefined在渲染时会被自动忽略

<div></div><div>{false}</div><div>{null}</div><div>{true}</div>

如果你想要一个值如false,true,null或undefined出现在输出中,你必须先将它转换为字符串:

react性能查看工具
在最新的React16版本中,我们可以直接在url后加上?react_pref,就可以在chrome浏览器的performance,我们可以查看User Timeing来查看组件的加载时间。

ps: 关于key的使用
关于key的使用我们要注意的是,这个key值要稳定不变的,就如同身份证号之于我们是稳定不变的一样。
一个常见的错误就是,拿数组的的下标值去当做key,这个是很危险的,代码如下,我们一定要避免。
将key设置为一个特殊字段,保证其唯一性

其他的检测工具

react-perf-tool 为React应用提供了一种可视化的性能检测方案,该工程同样是基于React.addons,但是使用图表来显示结果,更加方便。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么样的代码是好代码_什么是好代码?

什么样的代码是好代码编码最佳实践 (Coding Best-Practices) In the following section, I will introduce the topic at hand, giving you a sense of what this post will cover, and how each argument therein will be approached. Hopefully, this will help you decide w…

nginx比较apache

话说nginx在大压力的环境中比apache的表现要好&#xff0c;于是下载了一个来折腾一下。 下载并编译安装&#xff0c;我的编译过程有点特别&#xff1a; 1。去除调试信息&#xff0c;修改$nginx_setup_path/auto/cc/gcc这个文件&#xff0c;将 CFLAGS"$CFLAGS -g" …

计算机主板各模块复位,电脑主板复位电路工作原理分析

电源、时钟、复位是主板能正常工作的三大要素。主板在电源、时钟都正常后&#xff0c;复位系统发出复位信号&#xff0c;主板各个部件在收到复位信号后&#xff0c;同步进入初始化状态。如图7-11所示为复位电路的工作原理图&#xff0c;各个十板实现复位的电路不尽相同&#xf…

Docker制作dotnet core控制台程序镜像

(1)首先我们到某个目录下&#xff0c;然后在此目录下打开visual studio code. 2.编辑docker file文件如下: 3.使用dotnet new console创建控制台程序; 4.使用docker build -t daniel/console:dev .来进行打包; 5.启动并运行镜像; 6.我们可以看到打包完的镜像将近2G,因为我们使用…

【362】python 正则表达式

参考&#xff1a;正则表达式 - 廖雪峰 参考&#xff1a;Python3 正则表达式 - 菜鸟教程 参考&#xff1a;正则表达式 - 教程 re.match 尝试从字符串的起始位置匹配一个模式&#xff0c;如果不是起始位置匹配成功的话&#xff0c;match()就返回none。 re.search 扫描整个字符串并…

在Python中使用Twitter Rest API批量搜索和下载推文

数据挖掘 &#xff0c; 编程 (Data Mining, Programming) Getting Twitter data获取Twitter数据 Let’s use the Tweepy package in python instead of handling the Twitter API directly. The two things we will do with the package are, authorize ourselves to use the …

第一套数字电子计算机,计算机试题第一套

《计算机试题第一套》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《计算机试题第一套(5页珍藏版)》请在人人文库网上搜索。1、计算机试题第一套1、计算机之所以能自动运算,就是由于采用了工作原理。A、布尔逻辑。B 储存程序。C、数字电路。D,集成电路答案选B2、“长…

Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

一&#xff0c;环境说明 操作系统是Windows7家庭版&#xff08;有点不专业哦&#xff0c;呵呵&#xff01;&#xff09;&#xff0c;JDK是1.6的版本&#xff0c; Tomcat是apache-tomcat-6.0.35-windows-x86&#xff0c;下载链接&#xff1a;http://tomcat.apache.org/ Nginx…

git 版本控制(一)

新建代码库repository 1、在当前目录新建一个git代码库 git init git init projectname 2、下载一个项目&#xff0c;如果已经有了远端的代码&#xff0c;则可以使用clone下载 git clone url 增加/删除/改名文件 1、添加指定文件到暂存区 git add filename 2、添加指定目录到暂…

rollup学习小记

周末在家重构网关的Npm包&#xff0c;用到了rollup&#xff0c;记下笔记 rollup适合库library的开发&#xff0c;而webpack适合应用程序的开发。 rollup也支持tree-shaking&#xff0c;自带的功能。 package.json 也具有 module 字段&#xff0c;像 Rollup 和 webpack 2 这样的…

大数据 vr csdn_VR中的数据可视化如何革命化科学

大数据 vr csdnAstronomy has become a big data discipline, and the ever growing databases in modern astronomy pose many new challenges for analysts. Scientists are more frequently turning to artificial intelligence and machine learning algorithms to analyze…

object-c 日志

printf和NSlog区别 NSLog会自动加上换行符&#xff0c;不需要自己添加换行符&#xff0c;NSLog会加上时间和进程信息&#xff0c;而printf仅将输入的内容输出不会添加任何额外的东西。两者的输入类型也是有区别的NSLog期待NSString*&#xff0c;而printf期待const char *。最本…

计算机真正管理的文件名是什么,计算机题,请大家多多帮忙,谢谢

4、在资源管理器中&#xff0c;若想显示文件名、文件大小和文件类型&#xff0c;应采用什么显示方式。( )A、小图标显示 B、列表显示 C、详细资料显示 D、缩略图显示5、在EXCEL中&#xff0c;可以依据不同要求来提取和汇总数据&#xff0c;4、在资源管理器中&#xff0c;若想显…

小a的排列

链接&#xff1a;https://ac.nowcoder.com/acm/contest/317/G来源&#xff1a;牛客网小a有一个长度为nn的排列。定义一段区间是"萌"的&#xff0c;当且仅当把区间中各个数排序后相邻元素的差为11 现在他想知道包含数x,yx,y的长度最小的"萌"区间的左右端点 …

Xcode做简易计算器

1.创建一个新项目&#xff0c;选择“View-based Application”。输入名字“Cal”&#xff0c;这时会有如下界面。 2.选择Resources->CalViewController.xib并双击&#xff0c;便打开了资源编辑对话框。 3.我们会看到几个窗口。其中有一个上面写着Library&#xff0c;这里…

计算机 编程 教程 pdf,计算机专业教程-第3章编程接口介绍.pdf

下载第3章 编程接口介绍• DB2 UDB应用程序概述• 嵌入S Q L编程• CLI/ODBC应用程序• JAVA应用程序• DAO 、R D O 、A D O应用程序本章将介绍对DB2 UDB 可用的编程方法及其特色&#xff0c;其中一些方法附有简单的例子&#xff0c;在这些例子中&#xff0c;有些并不是只适用…

导入数据库怎么导入_导入必要的库

导入数据库怎么导入重点 (Top highlight)With the increasing popularity of machine learning, many traders are looking for ways in which they can “teach” a computer to trade for them. This process is called algorithmic trading (sometimes called algo-trading)…

windows查看系统版本号

windows查看系统版本号 winR,输入cmd&#xff0c;确定&#xff0c;打开命令窗口&#xff0c;输入msinfo32&#xff0c;注意要在英文状态下输入&#xff0c;回车。然后在弹出的窗口中就可以看到系统的具体版本号了。 winR,输入cmd&#xff0c;确定&#xff0c;打开命令窗口&…

02:Kubernetes集群部署——平台环境规划

1、官方提供的三种部署方式&#xff1a; minikube&#xff1a; Minikube是一个工具&#xff0c;可以在本地快速运行一个单点的Kubernetes&#xff0c;仅用于尝试Kubernetes或日常开发的用户使用。部署地址&#xff1a;https://kubernetes.io/docs/setup/minikube/kubeadm Kubea…

更便捷的画决策分支图的工具_做出更好决策的3个要素

更便捷的画决策分支图的工具Have you ever wondered:您是否曾经想过&#xff1a; How did Google dominate 92.1% of the search engine market share? Google如何占领搜索引擎92.1&#xff05;的市场份额&#xff1f; How did Facebook achieve 74.1% of social media marke…