React总结和遇到的坑
一、react项目
前端react后端node:https://github.com/GainLoss/react-juejin
前端react后端Pyton:https://github.com/GainLoss/python-react
二、react理解
1.react优点
组件、单向数据、虚拟DOM、生态系统、JSX
组件:一个组件就像一个接受道具作为输入并输出声明的函数接口。 UI应该由尽可能多的组件组成可以最大限度地提高可重用性。
单项数据:React使用单向数据流,因此只会更改数据结果更改UI。如果您使用Redux,则可以在全局应用程序中更改数据存储,组件监听那里的变化。
具体流程:(1)操作通过将数据传输到Dispatcher来启动数据流。(2)Dispatcher接收操作并将数据传递到所有store。(3)store包含应用程序的状态,并在收到相关操作后对其进行更新。(4)视图从store接收数据并重新呈现组件。
虚拟DOM:虚拟DOM允许UI在UI变化中具有高效性。这个组件应呈现的内部和之间的过程实际渲染是什么,它允许React在不同的工作平台。
生态系统:react有丰富的生态,有很多插件可以供开发者使用。
2.react和vue的对比
相同之处:(1)使用虚拟DOM (2)组件化
不同之处:(1)react如果状态变化,是从根节点开始重新渲染;vue是确定到某一个节点需要变化,只是更新这个节点;(2)react是用jsx渲染模板;vue使用的是Template模板渲染,还是Html模板;
选取:react生态比较好,插件多;vue学习难度低;
三、在创建项目的时候,各种坑和总结
关于react-router的坑和总结:
1.react-router现在版本是4,所以如果将嵌套的路由都放一块的话,就会出错:
报这种错误Warning: You should not use <Route component> and <Route children> in the same route;
所以将需要嵌套的路由放到你的组件中
2.在页面有导航的时候,我们需要实现点击导航跳转页面的功能,这时候我们需要在导航的render中这样写:
我们用Link: <li key={index}><Link to="/+{item.name}">{item.name}</Link></li> 而且我们需要引入一个import { Link } from 'react-router-dom'
3.我们想要获取当前页面的路由或者说是浏览器中地址栏的地址:
在当前组件中props里面有当前的地址,找一个恰当的生命周期钩子然后再这个函数中this.props里面就可以获取到,或者可以直接在render中return中元素里的{}里面直接获取
4.react-router路由有两种形式:
HashRouter这种的带hash #
BrowerBouter这种是利用html5中history的,这种是需要服务器端支持的,兼容性不是很好
6.有时候需要实现,根据当前地址实现对应导航显示:
在当前组件中获取this.props,然后将这个值赋给this.state,在需要当前组件中渲染导航组件的位置,在导航组件中写<Nav urlLocation={this.state.url}/>,最后在导航组件中获取到this.props里面包含的就是当前路由地址
7.有时候我们需要实现点击排序,给当前路由添加参数:我用的是Link这种方法
组件里面:
<div style={homeMainLeftTwodiv2}>
{
this.state.HomeMenutwo.map((item,index)=>
<span key={index} className={this.query===item.sort?"homesortactive":''}>
<Link to={{pathname:"/home",search: 'sort='+item.sort,}}>{item.name}</Link>
<Route path="/home/:id" component={Home}/>
</span>
)
}
</div>
在router路由中:还是和之前一样的
8.想只是改变地址栏的地址而不是调转页面,就比如我当前页面有两个选择,点击选择,改变地址栏地址,但是还是当前的组件
import createHashHistory from 'history/createHashHistory'
const history = createHashHistory() //点击一级菜单事件
clickTop(event) {
let that = this;
let tab = event.currentTarget.dataset.tab;
that.setState({ menuOne: tab })
console.log(that.setState)
history.push({
pathname: '/home/'+tab,
})
} {
this.state.HomeMenuTop.map((item, index) =>
<span key={index} className={this.state.menuOne === item.tab ? "homesortactive" : ""} data-tab={item.tab} onClick={this.clickTop}>
{item.name}{this.state.menuOne}
</span>
)
}
9.react-router2迁移到react-router4的特性:https://github.com/gmfe/Think/issues/6
10.在npm start之后页面出现这种错误Uncaught TypeError: Super expression must either be null or a function, not undefined
原因是:在编写组件的时候React.Component写错了
11.在react中使用事件:
如果没有用bind的话那么点击事件只在页面一开始的时候执行,不会在元素点击的时候执行,只有用this.click.bind(this)就可以,在点击元素的时候也执行这个函数
class FLeft extends React.Component{
constructor(props){
super(props)
this.state={
currentIndex:0,
} }
clickTab(index,e){
this.setState({currentIndex:index});
}
render(){
var styles={
width:'100%',
height:'300px'
}
var index=this.state.currentIndex;
return (
<div className="f_left">
<textarea className="f_left_text"></textarea>
<div className='f_left_text_choose'>
<span>图片</span>
<span>链接</span>
<span>话题</span>
<button>发布</button>
</div>
<div className='choose_tab'>
<span onClick={this.clickTab.bind(this,0)} className={this.state.currentIndex===0?'active':''}>推荐</span>
<span onClick={this.clickTab.bind(this,1)} className={this.state.currentIndex===1?'active':''}>动态</span>
</div>
</div>
)
}
}
12.在react中使用iconfont (Unicode编码)
一般使用的时候直接用<i className="iconfont">编码</i>这样就可以了,但是当你循环出来i标签的时候,那么iconfont使用的是字符串表示unicode编码,那么我们需要改写一下编码
想使用字符串来传递的话,只要将 "" 改为 “\ue655” 即可。
13.在react中循环中设置点击事件
这个里面只有把点击事件设置成异步的才不会循环出全部的元素的点击事件
<HomeHeader>
{
this.props.homeheader.map((item)=>{
var id=item.id;
return <HomeHeaderItem onClick={()=>this.props.clickChangeList(id)} key={item.id}><Link to={{pathname:'/home/'+id}}>{item.val}</Link></HomeHeaderItem>
})
}
</HomeHeader>
14.配置文件的路径:
有时候在一个组件中要引入一个新的组件,可能路径需要写很多的../,现在我们需要设置一个单词表示父级文件夹
背景:"react": "^16.5.2","react-dom": "^16.5.2","react-scripts": "2.0.4"
打开node_modules中的react-script中webpack.config.dev.js这个文件(是开发环境配置),里面的
resolve:{
alias: {
'react-native': 'react-native-web',
'@': paths.appSrc //对应的是相同文件夹下面的paths.js文件夹里面
},
}
设置完成之后,在组件中引入import Header from '@/common/header/header.js'
关于在react中引入css或者引入外部文件:
1.在react中怎么引入css文件呢:
{
test:/\.css$/,
exclude: /node_modules/,
loader: "style-loader!css-loader"
}
2.html元素中添加css样式的时候:
两种:一种是class名字填写,但是在jsx中class需要写成className; 二种是在行间写样式style={{}}里面放置样式 ;三种是style={colorstyle}里面放置一个变量
关于react中元素渲染和数据交互的总结:
this.state.HomeMenuone.map((item,index)=>
<span key={index}>{item.name}</span>
)
如果不加的话,会出这种错误
2.在react中引入图片的话,当然之前的直接放在src中也是可以的,但是比较好的方法是:
import img from './right.png'
<img src={img}/>
这种方法有可能会出现这种错误:出现Uncaught Error: Module parse failed: Unexpected character '�' (1:0),这种我的解决办法是重新npm install就可以了
3.在前后台交互的时候我用的是fetch实现的:
注意的是在fetch成功调取之后将结构赋给一个数组的时候,在then中需要用这个才能设置好this.setState({result:data}),然后map这个result
4.使用fetch获取后台数据:
fetch("/list/show").then((response)=>{
if(response&&response.status===200){
return response.json();
}
}).then((data)=>{
this.setState({result:data})
});
5.上面的是直接获取后台的数据,但是有时候我们需要用fetch给后台传参数(后台用的是express):
我们如果用get就是和上面是一样的,但是如果我们用post是有区别的和之前的写法,有两种写法:
一种:
if(this.props.location.search){
let idValue=this.props.location.search.split('=')[1];
fetch('/list/detail',{method:'POST',headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},body: `id=${idValue}`}).then((response)=>{
return response.json()
}).then((result)=>{
this.setState({result:result})
})
}
二种:
if(this.props.location.search){
let idValue=this.props.location.search.split('=')[1];
let formData = new FormData();
formData.append("id",123);
fetch('/list/detail',{method:'POST',body:
formData}).then((response)=>{
return response.json()
}).then((result)=>{
this.setState({result:result})
})
}
上面这两种都可以;
另外后台因为用的是express,所以你需要在dev-server.js中添加一个body-parser这个模块是为了解析客户端请求的body的内容,内部使用JSON编码,url编码处理以及对文件的上传处理。
关于react中事件处理的总结:
1.当我们想点击元素,相应的改变state的时候,可以这样:
//constructor
this.clickMenu=this.clickMenu.bind(this)
//点击事件
clickMenu(event){
var that=this;
let sort=event.currentTarget.dataset.sort;
that.setState({query:sort}) }
// render中
<div style={homeMainLeftTwodiv1}>
{
this.state.HomeMenuone.map((item,index)=>
<span key={index} className={this.state.query===item.sort?"homesortactive":'' } data-sort={item.sort} onClick={this.clickMenu}>
<Link to={ {pathname:"/home", search: 'sort='+item.sort,} } >{item.name}</Link>
<Route path="/home/:id" component={Home}/>
</span>
)
}
</div>
React总结和遇到的坑的更多相关文章
- react input的几个坑
[react input的几个坑] 1.input标签中设置value后,input进入controlled模式,valuechange由自动变为手动,导致input无法编辑.如: <input ...
- 【react native】有关入坑3个月RN的心路历程
由于一些原因,笔者最近变更到了RN的团队,回归到了hybrid app的开发的圈子中,固然是有蛮多新鲜感和新机遇的,不过遥想起以前在hybrid中各种view之前跳转的头疼等各种问题,笔者怀着忐忑的心 ...
- React Native 环境搭建踩坑
React Native (web Android)环境搭建踩坑(真的是一个艰辛的过程,大概所有坑都被我踩了 官方文档地址 : https://facebook.github.io/react-nat ...
- 谈谈出入React框架踩过的坑
1 在JSX的元素中写入内联样式,例如<div style={"color:blue"}></div> 报错:warning:Style prop valu ...
- 记一个react拖动排序中的坑:key
在做一个基于react的应用的时候遇到了对列表拖动排序的需求.当使用sortable对列表添加排序支持后发现一个问题:数据正确排序了,但是dom的顺序却乱了,找了一会儿原因后发现是因为在渲染数据的时候 ...
- react项目构建中的坑—淘宝镜像安装后要设置
基本的搭建步骤参考博客:https://blog.csdn.net/qq_27727251/article/details/86593415 这里要强调的坑是:安装完淘宝镜像要将其设置为默认Regis ...
- 【react native】rn踩坑实践——从输入框“们”开始
因为团队技术栈变更为react native,所以开始写起了rn的代码,虽然rn与react份数同源,但是由于有很多native有关的交互和变动,实际使用还是碰到蛮多问题的,于是便有了这个系列,本来第 ...
- 搭建react native所遇到的坑
一.所遇问题 在搭建react native环境中,遇到执行react native run-android命令出现如下问题 Could not resolve all dependencies f ...
- 【React Native】日常踩坑记录_以后将持续更新
作为一名有理想.有抱负的一代iOS程序员,本着“我头发够多,还能学”的原则,我选择了追随那些大佬的脚步,于2018年开始了React Native. 第一步:找文档.准备安装开发环境: 第二步:一步步 ...
随机推荐
- requests模块的一些总结
一.cookie模拟登录的三种方式 #!/usr/bin/env python # -*- coding: utf-8 -*- #author tom import requests post_url ...
- android apk重新[签名]
1,删除之前的签名文件 用解压缩工具打开,删除 [META-INF] 文件夹 2,打开命令行窗口 3,[保证签名文件和apk在同一级目录下] 然后执行如下命令,将 (xx) 处替换自己的签名.apk ...
- Nginx + Lua搭建文件上传下载服务
收录待用,修改转载已取得腾讯云授权 最新腾讯云技术公开课直播,提问腾讯W3C代表,如何从小白成为技术专家?点击了解活动详情 作者 | 庄进发 编辑 | 迷鹿 庄进发,信息安全部后台开发工程师,主要负责 ...
- enum学习
https://www.cnblogs.com/hyl8218/p/5088287.html
- Python+Selenium设置元素等待
显式等待 显式等待使 WebdDriver 等待某个条件成立时继续执行,否则在达到最大时长时抛弃超时异常 (TimeoutException). #coding=utf-8 from selenium ...
- Maths Intro - Probability
设事件A,B,C两辆独立,且满足ABC=空集,及P(A)=P(B)=P(C)=x,求max(x) x最大值为1/2分析: x值要保证所有的由A.B.C交或并得到的集合的概率测度在0到1之间. 先考虑A ...
- Android开发:使用Fragment改造TabActivity
TabActivity在API 13(Android 3.2)被标记为过期,需要使用Fragment来实现,Fragment是Android 3.0引入的一个概念,主要就是为了适应各种不同的屏幕大小( ...
- JS && || 陷阱 javascript 逻辑与、逻辑或 【转】
通常来说逻辑运算a&&b和a||b分别是逻辑与运算和逻辑或运算,返回的是一个布尔值,要么为true,要么为false. 比如在PHP里面a&&b返回类型永远是布尔值,非 ...
- 3..net可以做什么
.net可以做什么呢? (1)桌面应用程序 Winform(.net开发的桌面应用程序叫winform应用程序) (2)internet应用程序 ASP.net(.net开发的internet应用程 ...
- 2017年10月21日 数据库基础&三大范式
1. 数据库里面常用 int 整型nvarchar 字符串float 小数型decimal(,) 小数型money 小数型datetime 时间类型 ima ...