持续更新中......
初始化项目参考
A highly scalable, offline-first foundation with the best developer experience and a focus on performance and best practices.
参考:
初始化项目参考 https://github.com/react-boilerplate/react-boilerplate
reselect https://www.jianshu.com/p/6e38c66366cd
reselect https://github.com/reduxjs/reselect
immutable http://react-china.org/t/react-redux-immutablejs/9948
immutable https://blog.csdn.net/sinat_17775997/article/details/73603797
immutable http://facebook.github.io/immutable-js/docs/#/List/insert
react-immutable-proptypes https://github.com/HurricaneJames/react-immutable-proptypes
关于 redux-saga 使用的理解
因为 redux 存放的是全局数据,因此局部数据不应该放在 redux 中,否则会出现大量的 reset 作用的 action ,来保证系统看起来不会很奇怪,这明显是不合适的。
以下内容很好的解释了我的理解:
Redux store vs React state
试想一种情况,我们做一个 todo 应用,需要展示 todo 的列表,也要对单独
的 todo 进行分别编辑,那么 store 和 state 的设计无非就是如下两种:
无法显示图片
前面这种,将单独的 todo 的状态放在了 store 里,而后面这种是放在了 todo
组件的局部的 state 里。
一般来讲推荐后面这种,原因有二:
1. todo 组件是复用的,如果放在 store 里,在 SPA 的应用中,每次进入都
要**重置状态**;
2. 用作局部的 state,使得维护起来更加方便,因为在这个 case 里,对
todo 的临时操作**并不影响全局**。
在提交每个 todo 的时候,肯定要派发 store 中的 action(因为提交后整个
todolist 都会全局性的改变)。如果用前一种方案,todo 组件必然和 store 绑
定在了一起,所以可以在 todo 组件内部去 dispatch action。而对于后者,则
应该是通过 todolist 传入的回调方法去添加或者更新 todo 信息。
总结一下就是,使用前一种方式就不要画蛇添足通过父子组件传递回调的方
式去派发事件,因为 todo 组件已经不是独立的组件了,已经耦合到大的系统
里了,没必要增加复杂度了。而使用后一种方式就不要直接派发事件给
store,因为后一种方式的子组件本来设计思路就是解耦的。
XXX里的高票回答得很好:
Use React for ephemeral state that doesn't matter to the app globally
and doesn't mutate in complex ways. For example, a toggle in some UI
element, a form input state. Use Redux for state that matters globally or is
mutated in complex ways. For example, cached users, or a post draft.
Sometimes you'll want to move from Redux state to React state (when
storing something in Redux gets awkward) or the other way around (when
more components need to have access to some state that used to be local).
The rule of thumb is: do whatever is less awkward.
简而言之就是,如果这个状态不影响其他部分的业务逻辑并且足够简单,就使用 react state。
应该在什么位置获取异步数据
问:是不是所有的异步数据都要在 store 的 action 中获取?
答案是:否!前面那个小节已经讲过了局部 state 和全局 store 的关系,如何
选择完全看数据是否和全局有关联。推此即彼,异步数据的获取也同样。
如果获取到的数据是用来更新全局状态,那么当然要放在 store 的 action里。否则,直接在组件内部调用封装好的异步请求去改变局部的 state 就可以了。
参考:
http://react-china.org/t/react-redux-immutablejs/9948
react-router
如果两个页面 A、B,从A跳转到B,从B 返回后,A要保留进入B前的状态,那么B应该嵌套在A中,否则,A会被卸载,导致无法保留相关状态。
参考:
react-router http://reacttraining.cn/web/example/auth-workflow
https://github.com/reactjs/react-router-tutorial/blob/master/lessons/04-nested-routes/README.md
一个完整的react router 4.0嵌套路由的例子 https://blog.csdn.net/hsany330/article/details/78114805/
react 响应式 (根据屏幕大小显示不同的样式)
参考:
react-responsive The best supported, easiest to use react media query module. https://github.com/contra/react-responsive
css media https://www.jianshu.com/p/e4bf154db32d
在IOS系统12.1,iPhone X,微信版本6.7.4,弹窗中的输入框不好输入,因为软键盘隐藏后导致界面下方白屏
在代码中判断如果是IOS且是微信中打开的
{
const browserVrsions = yValidate.browserVrsions();
if (
browserVrsions.weixin
&& browserVrsions.ios
) {
window.scrollTo(0, 0);
}
}}
onFocus={() => {
const browserVrsions = yValidate.browserVrsions();
if (
browserVrsions.weixin
&& browserVrsions.ios
) {
window.scrollTo(0, 150);
}
}}
/>
判断客户端类型工具类:
const yValidate = {
browserVrsions: () => {
const u = navigator.userAgent;
// const app = navigator.appVersion;
return {
trident: u.indexOf('Trident') > -1, // IE内核
presto: u.indexOf('Presto') > -1, // opera内核
webKit: u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1, // 火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, // android终端
iPhone: u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, // 是否iPad
webApp: u.indexOf('Safari') === -1, // 是否web应该程序,没有头部与底部
weixin: u.indexOf('MicroMessenger') > -1, // 是否微信 (2015-01-22新增)
qq: u.match(/\sQQ/i) === ' qq', // 是否QQ
};
},
};
export default yValidate;
参考:JS判断客户端是否是iOS或者Android手机移动 https://segmentfault.com/a/1190000008789985
微信打开网页键盘弹起后页面上滑,导致弹框里的按钮响应区域错位 https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800
react 项目中使用环境变量操作步骤
- package.json
"start-test": "cross-env NODE_ENV=development npm_config_1=npm_config_1 webpack-dev-server --open --config webpack.config.js",
or
"start-test": "NODE_ENV=development webpack --env.npm_config_1=npm_config_1 webpack-dev-server --open --config webpack.config.js",
- webpack.config.js
plugins: [
new webpack.DefinePlugin({
'process.env.npm_config_1': JSON.stringify(process.env.npm_config_1),
}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
],
- use.js
console.log(process.env.npm_config_1, 'process.env.npm_config_1')
react+antd分页 实现分页及页面刷新时回到刷新前的page https://www.cnblogs.com/cristina-guan/p/9556274.html
当点击按钮后显示隐藏层,满足鼠标在div里操作不隐藏,在外边点击会消失的功能。逻辑上主要是阻止浏览器的冒泡
参考:https://codesandbox.io/embed/change-view-state-on-click-document-6sppw
javascript – 如何在React中通过ref获取组件的位置?https://codeday.me/bug/20190301/708340.html
react-router(v4) 路由跳转后返回页面顶部问题
遇到的问题
由A页面跳转到B页面,B页面停留在A页面的位置,没有返回到顶部。
问题分析
首先分析下出现此问题的原因: 在项目中使用的是 hashHistory,它是建立在 history 之上的,当路由发生变化时会记住原路由的状态,跳转新页面后默认停留在原页面的位置。
解决方法
- 使用 withRouter;
withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入。无需一级级传递react-router 的属性,当需要用的router 属性的时候,将组件包一层withRouter,就可以拿到需要的路由信息。
1、定义ScrollToTop组件,代码如下:
import React, { Component } from 'react';
import { Route, withRouter } from 'react-router-dom';
class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return this.props.children
}
}
export default withRouter(ScrollToTop);
2、在定义路由处引用该组件,代码如下:
ReactDOM.render((
),
document.getElementById('app')
);
这样就可以实现路由跳转后返回页面顶部,问题解决!
参考:
react-router(v4) 路由跳转后返回页面顶部问题 https://blog.csdn.net/abcde158308/article/details/84567077
sessionStorage多标签页共享
sessionStorage和localStorage区别
localStorage的生命周期是永久的,意思就是如果不主动清除,存储的数据将一直被保存。而sessionStorage顾名思义是针对一个session的数据存储,生命周期为当前窗口,一旦窗口关闭,那么存储的数据将被清空。最后还有一个很主要的区别同一浏览器的相同域名和端口的不同页面间可以共享相同的 localStorage,但是不同页面间无法共享sessionStorage的信息。
解决
所以我们可以借用localStorage的改变来主动修改sessionStorage,这里要用到一个监听事件storage,用于监听localStorage
window.addEventListener("storage", function(event){
//event.key确认修改的locaStorage变化key,event.newValue是修改后的值
if(event.key == "token"){
sessionStorage.setItem('token',event.newValue)
}
});
所以在登陆时直接localStorage.setItem('token','xxxxx'),这样自动设置在了sessionStorage中,需要用到的时候直接sessionStorage.getItem('token'),其实直接使用localStorage来记录登录状态什么的也可以,但是为了关闭页面直接清楚token,所以就在写sessionStorage中了
END~
参考:
sessionStorage多标签页共享 https://blog.csdn.net/deng1456694385/article/details/86537192
js格式化输入框内金额、银行卡号[转]
参考:
js格式化输入框内金额、银行卡号[转] https://www.cnblogs.com/mmzuo-798/p/6291279.html
需求:使用 rc-form 在一个大的页面中包含多个Form,验证如果有报错那么滚动到报错位置
参考:
https://www.jianshu.com/p/ecc2428c9afa
需求:使TweenOne支持bignumber显示
参考:
TweenOne数字变化 超过最大数值后,显示错误解决方案 https://www.jianshu.com/p/99ae4210679c
Chrome不能显示小于12px的字体的解决办法,同时解决-webkit-transform: scale不支持行内标签的问题
.forcefontsize10 {
display: inline-block;
font-size: 12px;
-webkit-text-size-adjust:none;
-webkit-transform : scale(0.83,0.83);
}
.forcefontsize8 {
display: inline-block;
font-size: 12px;
-webkit-text-size-adjust:none;
-webkit-transform : scale(0.66,0.66);
}
.forcefontsize6 {
display: inline-block;
font-size: 12px;
-webkit-text-size-adjust:none;
-webkit-transform : scale(0.5,0.5);
}
参考:
Chrome不能显示小于12px的字体的解决办法,同时解决-webkit-transform: scale不支持行内标签的问题https://blog.csdn.net/qq285744011/article/details/80229509
遇到的问题 react 调用this.setState()方法无效,不能改变对应的值,也不会调用render方法,更不会渲染出预期页面
解决方案1
this.visible = true;
this.forceUpdate();
render 中使用this.visible;
解决方案2
使用redux props里面的参数,修改该值dispatch action
参考:
避免取值时出现Cannot read property 'xx' of undefined
console.log(artcle?.authorInfo?.author); //Bowen
console.log(artcle?.timeInfo?.publishTime) //undefined
参考:避免取值时出现Cannot read property 'xx' of undefined
https://segmentfault.com/a/1190000018242053
tmp
参考: