react 踩坑第一天

1 搭建项目

  1. 安装node.js环境
  2. npm install -g create-react-app
  3. create-react-app  my-project
  4. cd my-project
  5. npm start

2 创建子组件的几种方式

1)函数式定义
  1. 函数式定义的无状态组件(负责根据传入的props来展示,不涉及到要state状态的操作)
  2. 特点
    1. 组件不会被实例化,整体渲染性能得到提升
      因为组件被精简成一个render方法的函数来实现的,由于是无状态组件,所以无状态组件就不会在有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。
    2. 组件不能访问this对象
      无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.refthis.state等均不能访问。若想访问就不能使用这种形式来创建组件
    3. 组件无法访问生命周期的方法
      因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。
    4. 无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用

例子:app.js

 
function App(props) {
  function showList() {
    return (
      <div>
        <p>{props.name}</p>//直接访问props
        <Ha />
      </div>
        
    )
  };
  return (
    <div className="App">
      {showList()}
    </div>
  );
}

export default App;

               

2 )  es5原生方式React.createClass定义的组件

特点:React.createClass创建的组件,其每一个成员函数的this都有React自动绑定,任何时候使用,直接使用this.method即可,函数中的this会被正确设置。

例子:

import React from 'react';
import ReactDOM from 'react-dom';
 
var InputControlES5 = React.createClass({
    propTypes: {//定义传入props中的属性各种类型
        initialValue: React.PropTypes.string
    },
    defaultProps: { //组件默认的props对象
        initialValue: ''
    },
    // 设置 initial state
    getInitialState: function() {//组件相关的状态对象
        return {
            text: this.props.initialValue || 'placeholder'
        };
    },
    handleChange: function(event) {
        this.setState({ //this represents react component instance
            text: event.target.value
        });
    },
    render: function() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange} value={this.state.text} />
            </div>
        );
    }
});
export default InputControlES5;

 

3 )es6形式的extends React.Component定义的组件

  特点:创建的组件,其成员函数不会自动绑定this,需要开发者手动绑定,否则this不能获取当前组件实例对象。         

   React.Component有三种手动绑定方法:可以在构造函数中完成绑定,也可以在调用时使用method.bind(this)来完成绑定,

         还可以使用arrow function来绑定。拿上例的handleClick函数来说,其绑定可以有:

  1  constructor(props) {
       super(props);
       this.handleClick = this.handleClick.bind(this); //构造函数中绑定
    }
   2  <div onClick={this.handleClick.bind(this)}></div> //使用bind来绑定
   3  <div onClick={()=>this.handleClick()}></div> //使用arrow function来绑定

例子:

import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
class Ha extends React.Component {
    constructor(props) {
        super(props);//必须存在super,否则你无法在构造函数中使用 this
        // 设置 initial state
        this.state = {
            moves:0,
            imgs:['./logo192.png','./logo192.png','./logo192.png','./logo192.png','./logo192.png','./logo192.png']
        
        };
    }
 
    option(flag){
        console.log(this); // React Component instance
        if(flag>0){
            this.setState({moves:this.state.moves+200})
          }else{
            this.setState({moves:this.state.moves-200})
          }
    }
    showList() {
       return (
            <div className='box'>
                <span className='icon1' onClick={this.option.bind(this,-1)}>left</span> 
                <ul className='list' style={{left:this.state.moves+'px'}}>
                    {   
                        this.state.imgs.map((item, index) => {
                            return (
                            <li key={index} >
                                <img src={item}/>
                            </li>
                            )
                            
                        })
                    }
                </ul>
                <span className='icon1' onClick={this.option.bind(this,-1)}>right</span> 
        </div>
        )
      } 
    render() {
        return (
            <div>
                {this.showList()}
            </div>
        );
    }
}
export default Ha;

3 解决onClick立即执行几种的方法+原理

原始写法:

onClick={this.某方法(某参数)}

正确写法:

onClick={() => this.某方法(某参数)}//用箭头函数定义一个新函数,返回结果是个函数

onClick={this.某方法.bind(this, 某参数)}//利用了bind的特性,不会立即调用,而是生成一个新的函数你想什么时候调就什么时候调
例子:
function add(a, b){
    return a+b;
}
var foo1 = add.bind(add, 5,3); 
foo1(); //8
var foo1 = add.bind(add, 5,3); 
foo1(); //8
 

问题点:

前者在声明时就直接执行了(因而加载页面自动执行),刚好在事件函数中也有setState操作,这样就会陷入到死循环中,不停的改变state,render()又不停的被执行。执行后的返回值赋给了onClick属性(返回值必然不会是个函数,因而再点击没有作用)

解决方案:只是声明阻止立即执行

4 react遍历数据,生成列表的几种方式(map,for )

注意:一定要返回,&返回的一定是dom结构

var arr = ['aaa', 'bbb', 'cccc']
var lesson = ['json', 'pp', 'll']
 
function showList(arr) {
    return (
        <ul>
            {
                arr.map((item, index) => {
                    return <li key={index}   >
                        {item}
                    </li>
                })
            }
        </ul>
    )
}
function a2(arr){
    var tem = []
    for(var i=0;i<arr.length;i++){
        tem.push(<li key={i}>{arr[i]}</li>)
    }
    return <ul>{tem}</ul>
}
posted @ 2021-03-10 17:50  青橙娃娃  阅读(61)  评论(0编辑  收藏  举报