唯雪博客

react常见错误整理

1. Uncaught TypeError: Cannot read property xxx of undefined

这个异常基本上是开发过程中最常见的异常了,引发异常的使用场景也有很多,举几个栗子:

  • 未初始化state的属性值便直接使用

class App extends Component {
    state = {}  
    componentDidMount() {
        axios.post('https://extension-ms.juejin.im/resources/gold', {category: 'frontend'})
            .then(res => {                
                this.setState({data: res.data.data});
            });
    }
    render() {
      return (
        <div className="App">
         {
           this.state.data.map(v => <span key={v.id}>{v.title}</span>)
         }
         </div>
     );
    }
}
// 处理方案有几种
// 1: 初始化state --> state = {data: []}
// 2: 采用短路写法 this.state.data && this.state.data.map()
  • 未初始化组件的props参数值

// 使用组件时,数据来自异步获取
// 1: 初始化props (推荐)
class Greeting extends React.Component { 
 static defaultProps = {   
    person: { name: 'react' }
 }

  render() {
      return (
            <div>Hello, {this.props.person.name}</div>
    )
  }
}
// 也可以
Greeting.defaultProps = {  name: 'Stranger'};
// 2: render时初始化
render() {    
const { person = {name: 'react'} } = this.props;
    return (
          <div>Hello, {person.name}</div>
    )
}
// 其他

2. this的绑定问题

testClick() {
    console.log(this.state.data)
}
render() {
    return (
            <button onClick={this.testClick}>测试</button>
    );
}

处理绑定的有三种方式:

(1) 调用函数时绑定:onClick={this.testClick.bind(this)}

(2) 构造函数中绑定:

constructor (props) {
    super(props)
   this.testClick = this.testClick.bind(this)
}

(3) 箭头函数:(个人推荐箭头函数,更便捷)

testClick = () => {
    console.log(this.state.data)
}

3. 循环key的问题

设置唯一的key值防止对已存在的dom重新渲染

this.state.data.map(v => <span key={v.id}>{v.title}</span>)
// 设置唯一性的id,不要设置循环的index
// bad
this.state.data.map((v, i) => <span key={i}>{v.title}</span>)

4. componentDidUpdate或componentWillUpdate 中更新state问题


// 一般问题是需要通过props来更新state导致的

// 老版本的在componentWillReceiveProps中修改
statecomponentWillReceiveProps(nextProps) {
    this.setState({data: nextProps.data});
}

// 16.3以后的新版本在getDerivedStateFromProps中更新
statestatic getDerivedStateFromProps(nextProps, prevState) {
    return {
            data: nextProps.data
    }
}

5. Objects are not valid as a React child 组件参数设置异常 或者直接渲染对象

render(){
    const obj = {a: 1};
        return (
                <span>{obj}</span>  
        // --> <span>{obj.a}</span>
    )
}
const CompA = (data) => <span>{data}<span> 
// --> ({data}) => <span>{data}</span>

6. 忘记export 组件

找到对应的组件,export 即可

7. .map (xxx) is not a function

和上面很类似,这个问题常发生在数据来自异步加载,没有进行相应的初始化或者初始化不规范,数据类型不一致导致的问题

8. 组件没有return DOM

// errorrender() {
    <div className="App">
        </div>
}
// yesrender() {
        return(
            <div className="App"> </div>
        )
}

9. 使用未知的标签或者组件名称使用小写

The tag <test> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

其实就是字面意思,找到对应的标签,改成首字母大写

10. 路由外使用link组件

使用Link的组件必须在用Router包裹的组件下使用

如果不是局部刷新的页面,可在最外层写一个空白的路由页面组件将内容页面包裹

const BlankPage = () => (
    <HashRouter>
        <Route path="/" component={App} />
    </HashRouter>)
export default BlankPage;

11. 跳转相同路由报错

Warning: You cannot PUSH the same path using hash history

<Link
    to={somePath}
    replace={somePath === this.props.location.pathname}
>
跳转
</Link>

// history操作,判断跳转路由相同的话,用replace
this.props.history.push  --> this.props.history.replace


白俊遥博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论