直接回答:React 里 render 的多行返回必须用括号包住,否则分号插入会让它返回 undefined;class 组件的方法默认不绑定 this,要么在构造函数里 bind,要么用箭头函数定义。
react中render返回的就是要渲染的,return多行的时候可以
1 | return ( |
*者可以单行
1 | return <div><div/> |
多个标签必须要用(),这样经过()运算,多行的就变成一个对象了
constructor是React 组件的构造方法
- 在 React 组件的构造方法 constructor 当中,你可以通过 this.state 为该组件设置自身的状态数据 需要保存状态的时候才使用构造函数
在使用 JavaScript classes 时,你必须调用 super(); 方法才能在继承父类的子类中正确获取到类型的 this 。
1 | class Square extends React.Component { |
Object.assign() 这样对数据进行了替换修改,rect中状态不能直接修改数据,只能这样进行替换修改 .slice()方法也可以做到
1 | var player = {score: 1, name: 'Jeff'}; |
将函数转换为类
- 你可以通过5个步骤将函数组件 Clock 转换为类
- 创建一个名称扩展为 React.Component 的ES6 类
- 创建一个叫做render()的空方法
- 将函数体移动到 render() 方法中
- 在 render() 方法中,使用 this.props 替换 props
- 删除剩余的空函数声明
1. 使用类就允许我们使用其它特性,例如局部状态、生命周期钩子
2. 类组件应始终使用props调用基础构造函数。
事件处理器会成为类的一个方法
1 | constructor(props) { |
将声明周期方法添加到类
每当Clock组件第一次加载到DOM中的时候,我们都想生成定时器,这在React中被称为挂载 同样,每当Clock生成的这个DOM被移除的时候,我们也会想要清除定时器,这在React中被称为卸载。
1 | componentDidMount() { |
阻止默认行为
React中不能通过返回false来阻止默认行为,只能通过e.preventDefault();
1 | function handleClick(e) { |
react跨页面传值
1. routerRedux方式
1 | import { routerRedux } from 'dva/router'; |
使用this.props.location.params接收值
2. link方式
1 | import { Link } from 'react-router-dom'; |
使用v2,v3this.props.location.query或者v4的this.props.location.search接收值
关于connect
connect之后model中的state就变成了被包装组件的props
判断对象是否为空
使用JSON.stringify(Object)==='{}'判断对象是否为空
npm的四种安装方式
1 | npm install moduleName # 安装模块到项目目录下 |
那么问题来了,在项目中我们应该使用四个命令中的哪个呢?这个就要视情况而定了。下面对这四个命令进行对比,看完后你就不再这么问了。
npm install moduleName 命令
- 安装模块到项目node_modules目录下。
- 不会将模块依赖写入devDependencies或dependencies 节点。
- 运行 npm install 初始化项目时不会下载模块。
npm install -g moduleName 命令
- 安装模块到全局,不会在项目node_modules目录中保存模块包。
- 不会将模块依赖写入devDependencies或dependencies 节点。
- 运行 npm install 初始化项目时不会下载模块。
npm install -save moduleName 命令
- 安装模块到项目node_modules目录下。
- 会将模块依赖写入dependencies 节点。
- 运行 npm install 初始化项目时,会将模块下载到项目目录下。
- 运行npm install --production或者注明NODE_ENV变量值为production时,会自动下载模块到node_modules目录中。
npm install -save-dev moduleName 命令
- 安装模块到项目node_modules目录下。
- 会将模块依赖写入devDependencies 节点。
- 运行 npm install 初始化项目时,会将模块下载到项目目录下。
- 运行npm install --production或者注明NODE_ENV变量值为production时,不会自动下载模块到node_modules目录中。
总结
devDependencies 节点下的模块是我们在开发时需要用的,比如项目中使用的 gulp ,压缩css、js的模块。这些模块在我们的项目部署后是不需要的,所以我们可以使用 -save-dev 的形式安装。像 express 这些模块是项目运行必备的,应该安装在 dependencies 节点下,所以我们应该使用 -save 的形式安装。
eslint 的三大通用规则
eslint官方提供了3种预安装包:
1. Google标准
eslint-config-google
执行安装:
1 | npm install eslint eslint-config-google -g |
2. Airbnb标准
eslint-config-airbnb它依赖eslint, eslint-plugin-import, eslint-plugin-react, and eslint-plugin-jsx-a11y等插件,并且对各个插件的版本有所要求。
你可以执行以下命令查看所依赖的各个版本:
1 | npm info "eslint-config-airbnb@latest" peerDependencies |
你会看到以下输出信息,包含每个了每个plugins的版本要求
1 | { eslint: '^3.15.0', |
知道了每个plugins的版本要求后,代入以下命令执行安装即可使用:
1 | npm install eslint-config-airbnb eslint@^#.#.# eslint-plugin-jsx-a11y@^#.#.# eslint-plugin-import@^#.#.# eslint-plugin-react@^#.#.# -g |
3. Standard标准
eslint-config-standard它是一些前端工程师自定的标准。
执行安装:
1 | npm install eslint-config-standard eslint-plugin-standard eslint-plugin-promise -g |
npm镜像
1 | npm config set registry https://registry.npm.taobao.org --global |
Yarn、React Native 的命令行工具(react-native-cli)
Yarn是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载。React Native 的命令行工具用于执行创建、初始化、更新项目、运行打包服务(packager)等任务。
1 | npm install -g yarn react-native-cli |
安装完 yarn 后同理也要设置镜像源:
1 | yarn config set registry https://registry.npm.taobao.org --global |
对象为空,操纵对象属性会报错
yiled双向传递消息
1 | function* foo(x) { |
在第一次运行it.next(),开始执行生成器函数,将hello返回给res(执行了yield后面的语句,将后面语句的结果返回,如果后面是函数,就执行函数,将函数结果返回,有return就返回,没有返回undefined),第二次执行next(),会将7传入给yield,继续运行至结尾,将最后返回的Y值返还给res 只有暂停的yield才能接受next()传来的值,所以第一个next()不会传值 最后一个next()返回的是return返回的值,如果没有return 就返回undefined
箭头函数的this是词法作用域,this绑定在创建它的对象上
关于import 的一点理解
1 | import test from './haha' |
umi设置base之后index.html中引入的文件路径不对
需要指定base、publicbaseh、和cssPublicPath,不然会导致css中不能正确访问图片
关于react中需要使用页面script标签中的变量
之前做的react中使用百度地图的时候需要在script标签中引入百度API,但是在react中无法使用BMap变量,我采取的办法是在window中获取,后来发现,在webpack中可以进行配置,实际是使用的
1 | module.exports = { |
这里面的BMap其实就是标签引入的script中在全局有了一个变量,变量的名字是BMap 可以参考这个webpack的介绍,和这个echarts中使用BMap
rect中的ref
ref实际是在组件dom加载到页面以后触发的,
1 | addMap = (a) => { |
上面的代码会在id为addMap实例化之后调用addMap函数,然后函数里面可以进行一些组件实例化之后才能进行的操作,比如画地图之类的
跨域时nginx的配置方法
1 | server { |
二.解释
1. Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置
Access-Control-Allow-Origin *后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
2. Access-Control-Allow-Headers 是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. 这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。这里涉及到 一个概念:预检请求(preflight request),请看下面"预检请求"的介绍。
3. Access-Control-Allow-Methods 是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
4.给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误
发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
三、 预检请求(preflight request)
其实上面的配置涉及到了一个W3C标准:CROS,全称是跨域资源共享 (Cross-origin resource sharing),它的提出就是为了解决跨域请求的。
跨域资源共享(CORS)标准新增了一组HTTP首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那 些可能对服务器数据产生副作用的HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
其实Content-Type字段的类型为application/json的请求就是上面所说的搭配某些 MIME 类型的 POST 请求,CORS规定,Content-Type不属于以下MIME类型的,都属于预检请求:
application/x-www-form-urlencoded multipart/form-data text/plain
所以 application/json的请求 会在正式通信之前,增加一次"预检"请求,这次"预检"请求会带上头部信息 Access-Control-Request-Headers: Content-Type:
OPTIONS /api/test HTTP/1.1 Origin: http://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type ... 省略了一些
服务器回应时,返回的头部信息如果不包含Access-Control-Allow-Headers: Content-Type则表示不接受非默认的的Content-Type。即出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
typescript类型检查中报错如何规避
在 css-module 中使用 由于 Pro 使用了 css-module,你可能需要
1 | import style from './index.style.less'; |
这时候 typescript 会报错,你可以 使用
1 | const style = require('./index.less'); |
避开这个问题。社区有很多相关讨论,暂时没有最好的办法,只有相对完美的 typings-for-css-modules-loader,同理导入图片,css,svg 也可以通过这种方式避开类型检查。
.? 可选链操作符
在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined,也可以和函数调用一起用,如果函数不存在则返回undefined
空值合并操作符(??)
??是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
界面添加下载excel文档功能
1 | export const download = (id, name) => { |
添加水印
1 | export const addWaterMarker = (str, ss1) => { |
最大化功能
1 | const fullScreen = (el) => { |
PM2的使用
1 | 1、 pm2需要全局安装 |
背景模糊
1 | backdrop-filter: blur(4px) grayscale(100%); |
关于useRef<boolean>();的另外一种用法,第一次渲染不运行某个函数
1 | const prevVisibleRef = useRef<boolean>(); |
当第一次渲染的时候prevVisibleRef值为underfind可以在useEffect中,给赋值为true,这样就避免在第一次的时候报错
1 | const useResetFormOnCloseModal = ({ |
这篇笔记整理自我自己的实践记录,如果做法有出入,或者你踩过别的坑,欢迎到留言板一起聊聊。