1. 引入图片出现404
- 在jsx中引入图片时,直接相对路径引入浏览器中运行会报404错误:使用require方法引入
<img src={require(../../saaets/images/bg1.png)}/>
- 在css中使用背景图时,直接相对路径引入即可:
body{ background-image: url('../../asstes/images/bg1.png') }
2. 在使用ant组件中的input组件时,如果遇到传参则与vue中不同:
// vue中
<Input @change="change($event, 'name')"/>
// react中
<Input onChange={this.change.bind(this, 'name')}/>
在js中获取时:
// vue
change(argus) {
const e = argus[0]
const name = argus[1]
}
// react
changeValue (name, e) {
console.log(name)
console.log(e)
}
3. 使用路由时,获取不到this.props.history
// 在组件中引入
import { withRouter } from 'react-router-dom'
class Demo extends React.Components {
......
}
export default withRouter(Demo)
4. 使用redux的步骤
/*
1. 首先在store文件夹中的module中划分模块,并在模块下建立一个js文件,如produxt.js
*/
import {createReducer} from 'redux-create-reducer'
import * as types from '../../../constants'
// 定义state
const state = {
formData: {
value1: '123'
}
}
// 定义类型
const TYPES = {
SAVE_FORM:`productOrder/${types.SAVE_FORM}`,
}
// Reducer
export const productOrder = createReducer(state, {
[TYPES.SAVE_FORM]: (state,action) => {
const {formData} = action.payload
state.formData = formData
return {
...state
}
},
})
/*
2. 在store下的index文件中引入,并注册
*/
import {combineReducers, applyMiddleware, compose, createStore} from 'redux'
import {connectRouter, routerMiddleware} from 'connected-react-router'
import {createBrowserHistory} from 'history'
import logger from 'redux-logger'
import {persistStore, persistReducer} from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import privateRoute from './private-router'
// 加载store
import {productOrder} from './module/pages/product/product-order'
export const history = createBrowserHistory()
const persistConfig = {
key: 'root',
storage,
}
const createRootReducer = (history) => combineReducers({
router: connectRouter(history),
productOrder
})
// 从localstorage获取保存的数据
const preData = localStorage.getItem('persist:root')
const preSate = preData ? JSON.parse(preData) : {}
for (let e in preSate) {
preSate[e] = JSON.parse(preSate[e])
}
// 替换键名为对应的Reducer名
if (preSate.router) delete preSate.router
const store = createStore(
persistReducer(persistConfig, createRootReducer(history)),
preSate,
compose(
applyMiddleware(
routerMiddleware(history), // for dispatching history actions
privateRoute,
logger
)
))
export default store
export const persistor = persistStore(store)
/*
3. 在组件中使用时要注意connect,使用form表单时注意Form.create
*/
const ProductForm = Form.create({
mapPropsToFields(props) {
let {formData} = props
const formKeys = Object.keys(formData)
const fields = {}
forEach(formKeys,item=>{
fields[item] = Form.createFormField({
value: formData[item],
})
})
return fields
},
onFieldsChange(props, changedFields) {
console.log(changedFields)
},
// 表单内输入框变化时
onValuesChange(_, values) {
console.log(values)
}
})(ProductOrder)
function mapStateToProps(state) {
const {formData} = state.productOrder
return {formData}
}
function mapDispatchToProps(dispatch) {
return {
saveUser:(data) => dispatch({type:'user/INCREMENT', payload:data})
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ProductForm))
5. 使用redux存储数据,页面刷新后数据丢失:采用redux-persist
// 在store的入口文件引入redux-persist
import { createStore, applyMiddleware, compose } from 'redux';
import { createLogger } from 'redux-logger';
import thunk from 'redux-thunk';
import reducers from './reducers/index';
import {persistStore, persistReducer} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const loggerMiddleware = createLogger();
const persistConfig = {
key: 'root',
storage: storage,
// stateReconciler: autoMergeLevel2 // 查看 'Merge Process' 部分的具体情况
};
const myPersistReducer = persistReducer(persistConfig, reducers)
const store = createStore(myPersistReducer)
export const persistor = persistStore(store)
export default store;
// 在项目的入口文件index.js中做如下修改
import React from 'react';
import ReactDOM from 'react-dom';
import axios from '@/axios/$axios';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Provider} from 'react-redux'
import store from './redux/store'
import {persistor} from './redux/store'
import {PersistGate} from 'redux-persist/integration/react';
// ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>, document.getElementById('root'));
6. table中的分页配置
<Table
columns={this.props.columns}
dataSource={this.props.dataSource}
rowKey={record => record.id}
bordered={true}
loading={this.props.loading}
size="small"
pagination={{
total: this.props.total,
pageSizeOptions: [10, 20, 30, 40, 50],
showSizeChanger: true,
showTotal: () =>{
return `共 ${this.props.total} 条`;
},
onChange: (page, pageSize) => {
this.props.onSizeChange(page, pageSize)
},
onShowSizeChange: (current, size) => {
this.props.onShowSizeChange(current, size)
},
}}/>
7. ant-design中表达如何赋值:
componentDidMount() {
// 表单赋值
let {form} = this.props
Object.keys(form.getFieldsValue()).forEach(key => {
const obj = {};
obj[key] = 1;
form.setFieldsValue(obj);
});
}
8. getFieldDecorator` will override `value`, so please don't set `value` directly and use `setFieldsValue` to set it.:不要直接给组件绑定value值了。
9. 在react项目中引入动画组件react-transition-group后,组件挂载执行两次,在componentDidMount中的请求接口连续两次。
================================================================================================
10. 配置按需加载时,运行npm run eject 报错This git repository has untracked files or uncommitted changes解决方案,按需加载配置过程参考:https://www.jianshu.com/p/46b099c1107a
1.初始化仓库
git init
2.添加并提交
git add .
git commit -m 'init project'
3.重新执行 npm run eject
11. 在使用ant-design-mobile定制主题时
// 1. 在项目根目录下建一个config-overrides.js文件,并安装"customize-cra"和"react-app-rewired"
const { override, fixBabelImports , addLessLoader} = require("customize-cra");
const theme = require('./antd-theme');
module.exports = override(
addLessLoader({
lessOptions: {
javascriptEnabled: true,
modifyVars: theme
}
}),
fixBabelImports("import", {
libraryName: "antd-mobile",
libraryDirectory: 'es',
style: true,
}),
);
// 2. 在package.json中将scripts修改为
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test"
}
12. 在进行 react
项目开发的时候,出现了这个错误,ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema
.这个实际上是 Less Loader
的版本导致的兼容性问题,需要更换 Less Loader
的版本,把 Less Loader
进行降级,通过 npm remove less-loader
命令卸载 Less Loader
,通过 npm i less-loader@5.0.0
命令安装 less-loader@5.0.0
的版本,然后问题就可以解决了。
13. react路由配置---react-router-dom参考:https://blog.csdn.net/liushijun_/article/details/94907262
*react中key的作用:标识了当前层级下节点的唯一性,判断节点能不能复用的前提是key和type;
*component与pureComponent的区别:pureComponent内置了一个生命周期(shoudComponentUpdate)自动比较state或者props有没有发证变化,但是是浅比较,
*diff算法,只有同一层级下key和type一致时才会复用;没有给默认的key时,用下标标识;
* 函数柯里化: 在一个函数中首先填充几个函数 在返回一个新的函数的的技术叫做函数柯里化
* 闭包: 可以访问自身作用域 父级作用域 父级函数参数作用域 直至找到全局作用域的函数叫做闭包
* 高阶函数:将函数作为参数或返回值的函数
* es6: 箭头函数 类 promise 生成器 块级作用域 set 对象解构 rest set 模板字符串
* redux: 全局唯一的数据源 store 可以通过 getState 拿到state 一个view对应一个state,state 的变化会导致view更新 但是用户拿不到state 只能通过view触发action来改变state
* action 是一个对象 必选包含 tpye 属性 store。dispatch() 是view触发action的唯一方法 store 接收到action事件后, 必须给一个新的state 然后view根据state发生变化 这种计算过程叫 reducer reducer 是一个纯函数 接收action和state作为参数 返回一个新的state
>* react 生命周期 挂载 渲染 卸载
* constructor 接收两个函数 props 和 context 使用 constructor 必须使用 super() this 指向
* componentWillMonut 一般用于服务端渲染
* componentDidMount 初次渲染 ajax 请求
* componentWillUnmount 组件卸载 清楚定时器 事件绑定
* componentWillReceiveProps 接收父组件改变后的props需要重新渲染组件的时候使用
* shouldComponentUpdate 用于优化控制组件重新渲染的生命周期 return false 可以阻止渲染
* componentDidUpdate 组件更新完毕
* render 插入 jsx 生成的虚拟dom 根据 diff 算法比对后进行渲染
* key 的作用 性能优化 diff算法会根据key进行比对 没有重新插入 有的话不会重新创建
> setState 异步 保持 state props refs 一致性 批量处理 多次合并成一次 优化性能
> react 组件传值
>* 父传子 props
>* 子传父 子调用父的方法传参
>* 兄弟传值 发布订阅模式
> http 和 https 的区别
>- http 使用80端口 https 使用 443 端口
>- https 比 http 要慢,因为HTTPS除了TCP握手的三个包,还要加上SSL握手的九个包
>- HTTP是超文本传输协议,是明文传输;HTTPS是经过SSL加密的协议,传输更安全
>- HTTPS需要申请证书
> HTTP2 四个新特性:
>- 多路复用,无需多个TCP连接,因为其允许在单一的HTTP2连接上发起多重请求,因此可以不用依赖建立多个TCP连接。
>- 二进制分帧,将所有要传输的消息采用二进制编码,并且会将信息分割为更小的消息块。
>- 头部压缩,用HPACK技术压缩头部,减小报文大小
>- 服务端推送,服务端可以在客户端发起请求前发送数据,换句话说,服务端可以对客户端的一个请求发送多个相应,并且资源可以正常缓存。
> 资源预加载
>* preload 页面加载过程中,在浏览器开始主体渲染之前加载
>* prefetch 页面加载后, 利用空余时间提前加载
> 浏览器渲染过程
>* 将获取到的html解析成 dom tree
>* 处理css 生成 cssom tree
>* 将DOM和CSSOM合并为渲染树(rendering tree),代表一系列将被渲染的对象。
>* 缓存
> 缓存机制 强缓存优先于协商缓存 若强缓存生效则直接使用强缓存 否则使用协商缓存 协商缓存由服务器决定是否使用缓存 若协商缓存失效则返回 200 重新返回资源和缓存标识 在存入浏览器缓存中 生效则返回 304 继续使用缓存
> Service Worker 必须是 https 然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。
> 强缓存 200 不会请求数据 直接从缓存中获取 header 中的Expires 和 Cache-Control 设置
> 协商缓存 304 查看本地缓存是否失效 携带缓存标示向服务器发起请求 由服务器根据缓存标识决定是否使用缓存 HTTP Header 实现:Last-Modified 和 ETag 。