react踩坑不完全指北(1)

来源:互联网 发布:化工公司工艺软件 编辑:程序博客网 时间:2024/06/05 03:09

1.return里只能返回一个非template父层根元素,并以此为基础进行嵌套

renderList = (        searchPlaceList.map( (item) => {          return (            <div className="separate-br">              <p>{item.name}</p>              <p>{item.address}</p>            </div>          )        })      )

而不能是

renderList = (        searchPlaceList.map( (item) => {          return (            <p>{item.name}</p>            <p>{item.address}</p>          )        })      )

2.JSX for {if…else…}
方案一

class HelloMessage extends React.Component {  render (){    let userMessage;    if (this.props.loggedIn) {      userMessage = (        <span>          <h2>{ `Welcome Back ${ this.props.name }` }</h2>          <p>You can visit settings to reset your password</p>        </span>      )    } else {      userMessage = (        <h2>Hey man! Sign in to see this section</h2>      )    }    return(      <div>        <h1>My Super React App</h1>        { userMessage }      </div>    )  }}

方案二

class HelloMessage extends React.Component {  renderUserMessage(){    if (this.props.loggedIn) {      return (        <span>          <h2>{ `Welcome Back ${ this.props.name }` }</h2>          <p>You can visit settings to reset your password</p>        </span>      );    } else {      return (        <h2>Hey man! Log in to see this section</h2>      );    }  }  render (){            return(      <div>        <h1>My Super React App</h1>        { this.renderUserMessage() }      </div>    )  }}

方案三:

class HelloMessage extends React.Component {  render (){    return(      <div>        <h1>My Super React App</h1>        { this.props.loggedIn ?            <span>              <h2>{ `Welcome Back ${ this.props.name }` }</h2>              <p>You can visit settings to reset your password</p>            </span>            :            <h2>Hey man! Log in to see this section</h2>        }      </div>    )  }}

方案四:

// 拆分成小函数class HelloMessage extends React.Component {  renderLogin() { // 如果这里有多行,推荐用这种方法    const {loggedIn, name} = this.props;    if (!loggedIn) return;    return (<span>      <h2>Welcome Back {name}</h2>      <p>You can visit settings to reset your password</p>    </span>);  }  render (){    return(      <div>        <h1>My Super React App</h1>        {this.renderLogin()}      </div>    );  }}

3.react-router带参数值跳转传值

 handleClick = (value) => {        browserHistory.push({            pathname: 'message/detailMessage',            query: {                title:value.title,                time:value.time,                text:value.text            },        })    }

.接收值

console.info(this.props.location.query.title)

4.多层数据遍历渲染(return必须得有)

<section>          {            Object.entries(groupCity).map((item, index) => {              return (                <div className="curr-city" key={index}>                  <p>{item[0]}</p>                  <p className="row txt-center">                    {                      item[1].map( (e, k) => {                        return (                          <span className="col-4" key={k} onClick={ () => this.goCity(e.id)}>{e.name}</span>                        )                      })                    }                  </p>                </div>              )            })          }        </section>

5.jsx数据渲染可以使用方法定义的返回值

 <Carousel          autoplay={false}          infinite          beforeChange={(from, to) => console.log(`slide from ${from} to ${to}`)}          afterChange={index => console.log('slide to', index)}        >          {msiteFoodTypes.map( (list, index) => {            return (              <a href="javascript:void(0)">                <Grid data={this.typeList(list)} square={false} className="not-square-grid" />              </a>            )          })}        </Carousel>

方法:

typeList (list){    return Array.from(list).map((val, index) => ({      icon: `${this.state.imgBaseUrl}${val.image_url}`,      text: `${val.title}`,    }));  }

6.使用Link标签进行路由跳转

// 字符串定位描述符 String location descriptor.<Link to="/hello">  Hello</Link>// 对象定位描述符 Object location descriptor.<Link to={{ pathname: '/hello', query: { name: 'ryan' } }}>  Hello</Link>// 函数返回定位描述符Function returning location descriptor.<Link to={location => ({ ...location, query: { name: 'ryan' } })}>  Hello</Link>

7.变量名不要和方法名重复,js识别不出来,误以为重写数据

const shopListArr = await shopList(latitude, longitude, offset);      dispatch(callShopList(shopListArr))

而非

const shopList = await shopList(latitude, longitude, offset);      dispatch(callShopList(shopList))

8.NPM安装NODE-SASS 使用SASS但是无法下载NODE-SASS
因为NODE—SASS在GitHub托管的是源码,需要用户自己编译。而编译需要Python和Visual C ++构建环境(Windows同学,其他操作系统Linux以及Mac不需要)最简单的办法就是通过上面的办法进行换源,淘宝源上的是编译好的,如果非要自己编译,请自行安装Python2.7以及Visual C ++生成工具,具体请参考官方文档
更新 NODE-SASS 只有CNPM 下载下来的是编译好的

9.can’t not find ‘xxModule’ 找不到相关资源
出现这个问题有两种原因:

引用路径有问题,npm包是直接Import React from ‘react’ 只需要写包名即可。而引用组件,静态资源是需要写相对路径的(有个问题就是所有文件里面的静态资源都需要import引入或者require引入,否则webpack无法得知依赖关系,而导致找不到)。
第二种就是相关包没有下载或者下载不齐全,项目根目录重新命令行NPM i 即可
10.React的给return出来的HTML添加事件报错this.xxxx.xxxx not a function
在class和模块的内部。默认是使用严格模式的,以及React的基类 Component 中所有的this都是指向class本身的,但是return出来的HTML 会被转化成实际的dom这个时候的this指向就不是定义的时候的那个class(个人肤浅理解)举例说明

import React, { Component } from  'react'class  APP  extends  Component {OnClick () {  console.log(2333)}render () {  return (    <button  onClick={this.OnClick}>按钮</button>    )  }}export default APP

以上代码逻辑上点击按钮会触发OnClick函数,但是实际上只会报错。
解决方法(推荐度由高至低):
1.使用提案阶段语法静态属性的提案,改提案在写累的实例属性的时候可以使用等式,从而将属性和方法写入类中。(提案阶段语法,需要单独的babel插件 官方脚手架create-react-app 已有此项配置(需要使用antd,sass,代码检查功能的可以参考这个脚手架

import React, { Component } from  'react'class  APP  extends  Component {OnClick  = () => {    console.log(2333)    }render () {return (    <button  onClick={this.OnClick}>按钮</button>   )  }}export default APP

2.在构造函数中bind(this)

import React, { Component } from  'react'class  APP  extends  Component {constructor () {    super()    this.OnClick = this.OnClick.bind(this)}OnClick () {  console.log(2333)}render () {  return (    <button  onClick={this.OnClick}>按钮</button>    )  }}export default APP

3.使用匿名箭头函数返回方法
此方法会生成不可服用的匿名函数,但是这个方法是可以主动给调用方法传参数的,慎重使用。

import React, { Component } from  'react'class  APP  extends  Component {OnClick () {  console.log(2333)}render () {  return (    <button  onClick={ () => this.OnClick }>按钮</button>    )  }}export default APP

11.使用Fetch,但是ie浏览器报错Fetch未定义,及其他浏览器set未定义Map未定义
Fetch是浏览器原生支持的,但是ie浏览器全系列都不支持promise,解决方案

1

npm install whatwg-fetch

然后项目入口文件内

import 'whatwg-fetch'

React使用了Es6的Set和Map数据结构低版本浏览器不支持,一劳永逸型方案(此方案是吧所有es6特性都通过es5函数模拟,弊端是会增加js文件体积,也可以自己百度挑单独的polyfill添加)
2.

npm install --save babel-polyfill

入口文件内

import 'babel-polyfill'

12.跨域问题
1.使用CORS 跨域方案,后端配置前端无忧请求只支持IE10+。
2.使用nginx反向代理,一劳永逸。
3.Webpack有开发代理功能
4.React官方脚手架create-react-app看这里

13.为什么我使用BrowserRouter开发环境正常,部署之后刷新就是404
这个问题是因为BrowserRouter 使用了HTML5的api导致每次url变化都是实际向服务器进行请求,所以需要后端收到前端路由请求之后都返回index.html。实在不会弄就去用HashRouter,url变化不会产生额外请求,因为他本质上一直是在/路径下

14.拦截页面。或者在页面进入之前做一些事情
请使用:

<Route path="/home" render={(props) => <div {...props}>Home</div>}/>

render接受一个函数会向函数附加一个参数,这个参数是所有的Router方法和参数,记得传给组件,可以在return之前做一些判断。

14.Cannot read property ‘xxx’ of undefined”
一般都是组件内部引用了props传下来的值,但是父组件没传,或者引用了不存在的值。

15.token: operator xxxxx
少了括号,多了逗号,多了括号巴拉巴拉的。

16.axios的 post 请求后台接受不到
axios默认是 json 格式提交,确认后台是否做了对应的支持;
装一个小模块qs

npm install qs -S

17.redux 的用户信息为什么还要存一遍在浏览器里(sessionStorage or localStorage)
因为 Redux的 store 干不过刷新啊.
保存在浏览器的缓存内,若用户刷新的话,在从里面取一下信息

原创粉丝点击