React之表格操作

对于官网上的那个表格demo又进行了改造,记录一下其中的困难和解决思路,当然还有功能没有完善,会继续利用空余时间来实现一下。


github:https://github.com/liuzaijiang/React-text

——————————————————————————————————————————————————————

在上一篇的基础上http://www.jb51.cc/article/p-hbsfoame-bch.html又做了一部分修改:

1.利用webpack进行了打包压缩处理,并提取出了的第三方库文件;

2.增加了按照价格排序的功能;新加商品后也能按照排序的方式来显示;

3.增加了分页的功能;

4.减少了组件不必要的render;

——————————————————————————————————————————————————————


webpack

webpack打包压缩我是参考这篇文章:http://www.jianshu.com/p/4df92c335617

当然现在webpack都已经是2.X了,所以还是会有版本迭代的:https://doc.webpack-china.org/guides/migrating/


然后我再稍微说几个需要注意的地方:

1.babel的loader中的名字要写成'babel-loader'

2.生成 .babelrc 文件需要写成 .babelrc. 这样的形式(前后各一个点)

3.如何设置NODE_ENV=production(React切换成产品模式)

在cmd中直接敲set NODE_ENV=production

然后在webpack.config.js中

plugins: [
             new webpack.DefinePlugin({
                'process.env': {
                        NODE_ENV: JSON.stringify('production')
                           }
                     }),]

4.将第三方库另外打包一份(比如我们的react,react-dom这样的第三方js,最好和我们自己定义的js分开,这样webpack利用diff算法打包的时候也会快一点,毕竟这些第三方库我们基本不会去修改)

entry: {
	bundle:__dirname + "/app/main.js",vendor:["react","react-dom"]
	},
我们需要再entry中定义好,然后再plugins中利用webpakc自带的插件进行打包
plugins: [
	   new webpack.optimize.UglifyJsPlugin({
		output: {
		    comments: false,// remove all comments
		 },compress: {
		    warnings: false
		 }
	     }),new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' }),new webpack.DefinePlugin({
		 'process.env': {
		   NODE_ENV: JSON.stringify('production')
		  }
		}),]


5.利用webpack-dev-server进行修改后实时刷新

自从每次打包后我这边每改一次都要所有的重新打包,需耗费我10多秒的时间,真的是太....那个啥了;


不过在使用过程中我遇到了一个困难,就是随便运行成功了,但是无法实时刷新;

我的解决方法如下:(都是针对我自己的demo进行修改,实际情况实际讨论)

首先在package.json这个文件中进行修改

"scripts": {
    "start": "webpack","dev":"webpack-dev-server --inline --content-base build/"
  },

我们运行npm install start的时候是常规的打包,运行npm run dev是启动webpack-dev-server,--content-base 后面接的是index.html文件的路径,我是放在build/下面的

然后修改一下webpack.config.js

output: {
        path: __dirname + "/build/js",filename: "[name].js",publicPath: 'js/'
    },
最后修改一下index.html
<script src="js/vendor.js"></script>
<script src="js/bundle.js"></script>

这样就可以实现实时修改文件,然后浏览器会自己刷新了。

最后我还是想说一下为什么会出现这个原因,我个人的理解是,开启webpack-dev-server后进行修改打包其实只是在内存中运行,我path中指定的路径生成的js是没有改变的;这样我index.html引用的脚本路径就要正确才行。我在output中定义了publicPath变量。

path:用来存放打包后文件的输出目录
publicPath:指定资源文件引用的目录

如果不指定publicPath路径,则默认为根路径,根路径是 这个 http://localhost:8080/,而我以前的路径是../js/xxx.js(这个是当前路径的上个路径中的js文件夹,但是我用服务器开启后,当前路径就是http://localhost:8080/),这样是肯定找不到的。

如果我不指定路径,那么index.html中可以就直接这样xxx.js引用js,我这里指定了publicPath : js/" 其实是http://localhost:8080/js,然后引用的时候写成js/xx.js即可,这样做是为了和我本地编译打包的脚本路径一致。





分页

对于分页,这里我花了比较多的时间:

以前做过jq的分页,知道了大体的思路,首先是需要知道一共有多少个数据,然后是每页显示多少行,然后就是求出一个页数,再对表格中的数据进行选择性的显示。


但是刚接触到React分页的时候还是一头雾水,有点不知道从哪下手,毕竟React不能那么容易就能操作到每一个节点,轻松获取我们想要的数据。


我这边的思路首先是从显示和隐藏每一行开始,因为每一行我这边封装成了一个小组件,我这边完全可以控制其display属性来显示,不过这里需要注意的就是不能用jq的那种方法,addClass,removeClass或者是.css来控制,我们需要用变量来控制,比如:

var display="none" 
<tr style={{display:display}} />

这里通过改变display变量来控制显示。


当我们能够去显示和隐藏每一行后,就需要来进行选择性显示了和隐藏了;

if(this.props.index<this.props.currentPage*this.props.eachPage||this.props.index>(this.props.currentPage+1)*this.props.eachPage-1){
			display="none";
		}


this.props.index是当前这一行的索引,即数据当前行数;

this.props.currentPage是当前页数;

this.props.eachPage是每一页显示行数;

比如,我们要显示第一页的数据,每一页显示5个数据,那么显示的具体行数就是0--4,那么小于0的和大于4的我们就会去隐藏。

这里的this.props.currentPage其实是个变量,是和另一个页面跳转的组件进行通信的,中间就需要用父组件当作一个媒介来传递。当我点击下一页,或者选择具体的页数进行跳转的时候,需要改变这个数据。



当然我们还需要进行一些边界问题的处理:

A.比如我们目前是第一页,那么我们的首页和上一页就要被灰掉,不能进行点击触发,我们处于最后一页的时候需要把下一页和尾页同样灰掉;

我的做法如下:

类似于前面的隐藏和显示,我这里给首页,前一页,下一页,尾页都添加了一个变量"ban"为它的className(ban设置的CSS是灰掉这个按钮);

然后我们就进行判断,当前是首页还是尾页,相应的对这个ban变量进行赋值,如果不满足条件就赋值一个空值,满足就赋值我们定义好的css变量;

到这里我们只是对css进行了灰掉,但是你点击的时候还是会触发函数,所以我这里又在点击的时候又进行了一次判断;由于我这里是利用的事件代理,所以对于这4个按钮我只是定义了一个click函数,然后判断他们的id,来进行判断到底是哪个按钮,在这个基础上我再判断是否className为ban,如果是,则不会去触发。


B.如果我现在处于最后一页,我需要去删除掉最后一个数据,那么表格应该会自动跳转到前一页。

(这个问题对我来说也是具有挑战性的)

我的思路如下:


首先判断当前是不是最后一页(如果不是,你删除数据,表格会自动更新,后面的数据会补上)

如果是最后一页,再判断是不是最后一个数据(这里的最后一个数据是所有数据的最后一个,那样这样删除跳转就没有意义,而且还会产生bug)

如果不是最后一个数据,再判断是不是最后一页的最后一个数据(如果不是,后面会数据会补齐)

如果是,就更新当前的页数为上一页


ps:这里判断总页数的方法可以参考一下,我这里是用总商品除以每页显示的行数,pasreInt是去除小数部分,如果正好可以整除,那么除出来的数据正好可以当作页数,如果不能整除的话,那么就向上取舍。(具体情况还是具体分析吧,我这里的总页数是1,2,3但是我当前页是0,1,2)

if(this.state.products.length/this.state.eachPage==parseInt(this.state.products.length/this.state.eachPage))
	{
		var page=parseInt(this.state.products.length/this.state.eachPage);
	}
	else
	{
		var page=Math.ceil(this.state.products.length/this.state.eachPage);
	}
		
if(this.state.currentPage==page&&this.state.products.length!=0&&this.state.products.length%this.state.eachPage==0)
	{
	    this.setState({
		products:this.state.products,currentPage:this.state.currentPage-1
	     })
	}
	else{
	    this.setState({
		products:this.state.products,})
	}


最后还需要注意的就是,我这里跳转具体页数是select选项和前一页它们按钮触发方式不一样,前者是onChange后者是onClick



减少render

其实组件更新的时候,很多相关组件也会同时更新渲染,有些组件是死的,有些是没必要更新的,所以这里我们可以选择性进行更新。

这里就是当它的isAdd属性改变了我就进行更新,这个就是我们的添加商品的窗口,只有我点击添加了再进行组件渲染,其他时候没必要进行组件渲染。

shouldComponentUpdate(nextProps,nextState) {
 if (this.props.isAdd !== nextProps.isAdd) {
	return true;
	}
 return false;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom