a .安装
npm install -g yarn
b. cmd中不是内部命令的解决
此电脑–> 高级系统设置–>环境变量–> 用户变量–> 找到yarn文件所在目录,不是bin目录
c. yarn在powershell中运行失败的解决方法
1、到C:\Windows\System32\WindowsPowerShell\v1.0 目录下,右键选择以管理员身份运行powershell.exe
2、执行set-ExecutionPolicy RemoteSigned,选择Y就可以了
npm install -g create-react-app //安装react脚手架工具
create-react-app project //创建react脚手架项目
//或者 npx create-react-app 项目名称
cd project //切换到项目文件夹
npm start //运行react项目
ps:特别注意
不要直接修改
禁止 this.state.time=new Date()`
不能直接更新
禁止 let { comments } = this.state
推荐 let comments = [ ...this.state.comments ]
2)前端应用需要通过Ajax请求与后台进行数据交互;
1)jQuery:比较笨重,如果需要另外引入不建议使用;
2)Axios : 轻量级,建议使用,而且是promise风格的,可以解决回调地狱;
3)fetch : 原生函数,但是老版本的浏览器不支持,可以使用fetch.js,符合关注点分离;
4)fly : 微信小程序比较常用;
"proxy":"http://localhost:4000"
npm install http-proxy-middleware --save
or
yarn add http-proxy-middleware
export default class App extends React.Component{
render(){
return <div style={
{
width:"100px"}}> </div>
}
}
如果只需要添加一个类名
<div className={
index===this.state.currentIndex?"active":null}>此标签是否选中</div>
如果本身有其他的className,又需要添加其他的类名
<div className={
["container tab", index===this.state.currentIndex?"active":null].join('空格')}>此标签是否选中</div>
或者模板字符串
<div className={
`container tab ${
index===this.state.currentIndex?"active":null}`}>此标签是否选中</div>
单个样式的写法
<div style={
{
display: (index===this.state.currentIndex) ? "block" : "none"}}>此标签是否隐藏</div>
多个样式的写法
此标签是否隐藏
安装
1)工具名称 :PubSub-js
2)下载 npm install pubsub-js
使用方法Github详细地址
// 引入的两种方法
import PubSub from 'pubsub-js'
// or when using CommonJS
const PubSub = require('pubsub-js');
//发布
PubSub.publish('pubsub',data)//发布一个事件名称
//订阅
PubSub.subscribe('pubsub',function(msg,data){
//data是我们需要接收的数据,然后我们进行操作
console.log(data)
})
1)共同的数据需要放在父组件上,特有的数据放在自己的组件内部;
2)通过props传递数据,需要一级一级的传递,特别的繁琐;
3)一般属性–> 父组件传递数据给子组件–> 子组件读取数据;
4) 函数属性–> 子组件传递数据给父组件–> 子组件调用函数;
5) 适用场景:最好应用在父传子上面,子传子也可以;
//jsx
<Button>点我进行跳转</Button>
//获取
console.log(this.props.children)
组件是 React 的核心功能,其拥有非常强大的声明式编程模型。React Router 是导航组件的集合,可与你的应用程序进行声明式的组合。无论你是想为你的 Web 应用程序添加书签,还是在 React Native 中进行组件化导航,React Router 都可以在 React 的任何位置渲染使用 - 所以请考虑使用!
npm install react-router-dom
路由切换的时候,路由组件卸载了,可以在路由组件的生命周期componentWillUnmout周期中进行打印
2)History API
a. History.createBrowserHistory():得到封装window.history的管理对象;
b. History.createHashHistory:得到封装window.location.hash的管理对象;
c.history.push() :添加一个新的历史记录;
d.history.replace():用于添加一个新的历史记录替换当前的记录;
e.history.goBack(): 回退到上一个历史记录;
f.history.foForward(): 前进道下一个历史记录;
g.history.listen(function(location){}): 见识历史记录的变化;
//历史路由
//hash路由
//路由器 ,包裹的外壳
// 路由 ,负责路由组件的切换
// 路由重定向
//附带动态切换的a 标签
// 只匹配一个的组件
浏览器的历史记录,是栈结构,是一种数据结构
//在路由组件中获取this.props
this.props.history.push() //默认跳转,存在路由栈中
this.props.history.replace() //没有历史记录;
this.props.history.goBack() //返回上一级页面
this.props.history.goWord() //前进一个页面
import {
Link ,NavLink} from "react-router-dom";
<Link to="/url"></Link>
<NavLink to="/url"></NavLink>
@import '~antd/dist/antd.css';// ~ 在工程化、组件化中代表的是node_modules文件夹
npm install babel-plugin-import --dev // 安装按需引入插件,必须
a. 拉取配置之后,在page.json文件中添加如下代码;
b. 书写完毕,然后直接引入插件,不必引入样式文件即可使用;
npm install react-app-rewired --dev
/* package.json 的配置需要做如下修改*/
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom",
}
const {
override, fixBabelImports, addLessLoader } = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: "css",
}),
addLessLoader({
javascriptEnabled: true,
modifyVars: {
'@primary-color': '#ada57a' },
})
);
import {
Button } from 'antd';
npm install react-app-rewired customize-cra babel-plugin-import //下载三个插件的安装包
react-app-rewired //修改默认配置
customize-cra //按需加载
babel-plugin-import //动态引入的
ps:使用[email protected] $ yarn add react-app-rewired customize-cra@next,否则自定义主题会报错
npm install react-app-rewired customize-cra@next babel-plugin-import //下载三个插件的安装包
npm install less less-loader //安装less的相关配置
在项目的根目录创建config-overrides.js文件 ,然后改写config-overrides.js
const {
override,fixBabelImports,addLessLoader}=require('customize-cra');
module.exports=override(
flxBabelImports("import",
{
libraryName:"antd",
liararyDirectory:"es",
style:true,
}
),
addLessLoader({
javascriptEnabled:"true",
modifyVars:{
"@primary-color":"yellow"}
})
)
ps:注:如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
概念:
高阶函数:一个函数接收 一个函数作为参数或者函数调用的返回值是一个函数
高阶组件:一个组件接收一个组件加工成一个新的组件,就叫做高阶组件。
1)reudx 英文网
2)redux 中文网
3)github官网
//NPM
npm install redux
//或者
// Yarn
yarn add redux
1) redux是一个独立专门用于做状态管理的JS库(不是react插件库);
2)它可以用在React、Angular、Vue等项目中,但是基本上与React配合使用;
3)作用:集中式管理(读/写)React应用中多个组件共享的状态;
1)总体原则:能不用就不用,如果不用比较吃力才考虑使用;
2)某个组件的状态,需要共享;
3)某个状态需要在热河地方都可以拿到;
4)一个组件需要改变全局状态;
5)一个组件需要改变另一个组件的状态;
createStore()
1)作用:创建包含指定reducer的store对象;
2)代码:
import {
createStore} from "redux"
import counter from "./reducers/counter"
const store=createStore(counter)
store 对象
1) 作用:redux库最核心的管理对象,它的内部维护这state、reducer
2)核心方法:dispatch(action)、getState()、subscribe();
store.getState() //获取数据
store.dispatch(action) //派发动作
store.subscribe(callback) //检测store的改变并重新渲染页面
1) 一个react的插件库;
2)专门用于简化在react应用中使用redux;
npm install --save react-redux
1)UI组件
2)容器组件
所有组件都可以得到state数
<Provider store={
store}>
<App/>
</Provider>
用于包装UI组件生成器组件
import {
connnect } from "react-readux";
connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
connect()精简写法
connect(
state = > ({
count:state}),
//mapDispatchToProps 精简写法
{
increment:incrementAction,
decrement:decrementAction
}
)
将外部的数据(及state对象)装换为UI组件的标签属性
const mapStateToprops=function(state){
return {
value:state
}
}
将分发action的函数转换为UI组件的标签属性,简洁语法可以直接指定actions对象或包含多个action方法的对象
npm install --save redux-thunk
import {
createStore, applyMiddleware } from 'redux';
import {
operationCount } from './reducers';
import thunk from 'redux-thunk';
//执行一个middle中间件
export default createStore(operationCount, applyMiddleware(thunk));
//分发一个异步action
export const incrementCreatorAsync = (data, delay) => {
return (dispatch) => {
setTimeout(() => {
dispatch(incrementCreator(data));
}, delay);
};
};
npm install redux-devtools-extension --save-dev
在store.js文件中引入,然后改写store.js文件
import {
composeWithDeVTools } from "redux-devTools-extension";
export default createStore(reducer,composeWithDevWith(applyMiddleware(thunk)))
使用原生js对象的文档碎片(fragment)的功能
将需要添加的大量元素 先添加到文档碎片中,再将文档碎片添加到需要插入的位置,大大 减少dom操作,提高性能(IE和火狐比较明显)
key是虚拟Dom对象的标识,在更新显示时,有着重要的作用,当数据发生改变时,React会生成新的虚拟Dom,随后React将之前的旧虚拟Dom和新的虚拟Dom进行比较
a. 旧的虚拟Dom中找到了与新的虚拟Dom中相同的key
– 若虚拟Dom没有发生改变,直接使用原来的真实Dom,不去刷新页面;
– 若虚拟Dom发生了改变,先更新虚拟Dom,随后刷新页面的真实Dom;
b.旧的虚拟Dom中没有找到相同的key
– 根据数据创建新的虚拟Dom,随后渲染真实Dom到页面;
2).使用index索引作为key值得问题
添加删除排序会产生不必要的真实Dom更新,界面效果可能没有问题,但是效率比较低
如果真实Dom元素有输入框或者多选框等,会产生错误的真实Dom更新、
ps:如果不存在添加删除和排序则使用index索引作为key值是没有问题的
3).key值得解决方案
使用数据中对象中的id唯一标识
正常情况下推荐使用受控组件,除非input输入框的存在特别多的情况下,才会去考虑使用非受控组件
字符串的使用方式 this.refs.input (使用最多的情况)
回调函数的使用方式 (炫技的情况)
(this.input=input)}>
createRef API的使用 (最恶心的使用情况)
myRef=React.createRef()
//获取方式
this.myRef.current.value
this.props.children
移除
componentWillMount
和componentWillReceiveProps
将要被移除,这被官网认为是不安全的。如果使用的话,需要在方法前面添加 UNSAFE_
,例如UNSAFE_componentWillMount()
生命周期(新)最新更新
**getDerivedStateFromProps ** 用于取代:componentWillMount 和 componentWillUpdate
getSnapshotBeforeUpdate 介于render和componentDidUpdate之间,而且必须和componentDidUpdate配合使用,几乎不会被使用;此生命周期的任何返回值将作为参数传递给 componentDidUpdate()
,此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。
应返回 snapshot 的值(或 null
)。
更新的过程