React Learning(Day2)(2019.7.6)

2019-07-13  本文已影响0人  Allenem

React Learning(Day2)(2019.7.6)

日常挤牙膏

一、拆分组件与组件之间的传值

import Child from './Child'

return(
  <Child/>
)
import React, {Component,Fragment} from 'react'
import './style.css'
import TodoItem from './TodoItem'

class Todolist extends Component {

  constructor(props){
    super(props);
    this.state = {
      inputValue: '',
      list: []
    };
  }

  render() {
    return (
      <Fragment>
        <div>
          {/* 注释写法1 */}
          {
            // 注释写法2
          }
          <label htmlFor='insertArea'>输入内容:</label> 
          {/* 注意for用htmlFor代替 */}
          <input
            id='insertArea'
            className='input' // 注意class用className代替
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)} //函数的this绑定组件对象的this
          />
          <button onClick={this.handleBtnClick.bind(this)}>提交</button>
        </div>
        <ul>
          {
            this.state.list.map((item,index) => {
              return (
                <div>
                  <TodoItem 
                    content={item} 
                    index={index}
                    deleteItem={this.handleItemDlete.bind(this)} // this绑定到父组件
                  />
                  {/* <li 
                    key={index} 
                    onClick={this.handleItemDlete.bind(this,index)}
                    dangerouslySetInnerHTML={{__html: item}}
                  >
                  </li> */}
                </div>
                
              ) 
            })
          }
        </ul>
      </Fragment>
    );
  }

  handleInputChange(e){
    // console.log(this);
    this.setState({
      inputValue: e.target.value
    });
  }

  handleBtnClick(){
    this.setState({
      list: [...this.state.list,this.state.inputValue],
      inputValue: ''
    });
  }

  handleItemDlete(index){
    // immutable
    // state 不允许我们做任何更改,可以修改副本
    const list = [...this.state.list];
    list.splice(index,1);
    this.setState({
      list:list
    })
  }

}

export default Todolist;
import React, { Component } from 'react'

class TodoItem extends Component {

  constructor(props) {
    super(props);
    this.handleClick=this.handleClick.bind(this);
  }

  render() {
    return (
      <li
        onClick={this.handleClick}
        //key={this.props.index}
      >
        {this.props.content}
      </li>
    )
  }

  handleClick() {
    this.props.deleteItem(this.props.index);
    //alert(this.props.index);
  }
}

export default TodoItem

二、代码优化

优化后代码如下:

import React, {Component,Fragment} from 'react'
import TodoItem from './TodoItem'
import './style.css'

class Todolist extends Component {

  constructor(props){
    super(props);
    this.state = {
      inputValue: '',
      list: []
    };
    this.handleInputChange=this.handleInputChange.bind(this);
    this.handleBtnClick=this.handleBtnClick.bind(this);
    this.handleItemDlete=this.handleItemDlete.bind(this);
  }

  render() {
    return (
      <Fragment>
        <div>
          <label htmlFor='insertArea'>输入内容:</label> {/* 注意for用htmlFor代替 */}
          <input
            id='insertArea'
            className='input' // 注意class用className代替
            value={this.state.inputValue}
            onChange={this.handleInputChange} //函数的this绑定组件对象的this
          />
          <button onClick={this.handleBtnClick}>提交</button>
        </div>
        <ul>
          {this.getTodoItem()}
        </ul>
      </Fragment>
    );
  }

  getTodoItem(){
    return this.state.list.map((item,index) => {
      return (
        <TodoItem 
          key={index}
          content={item} 
          index={index}
          deleteItem={this.handleItemDlete} // this绑定到父组件
        />
      ) 
    })
  }

  handleInputChange(e){
    // console.log(this);
    // 旧版
    /* this.setState({
      inputValue: e.target.value
    }); */
    //新版,对象变函数,异步,将e.target.value存在外层
    const value = e.target.value;
    this.setState(() => ({
        inputValue: value
    }))
  }

  handleBtnClick(){
    /*this.setState({
      list: [...this.state.list,this.state.inputValue],
      inputValue: ''
    });*/
    this.setState((prevState) => ({
      list: [...prevState.list,prevState.inputValue],
      inputValue: ''
    }))

  }

  handleItemDlete(index){
    /*
    const list = [...this.state.list];
    list.splice(index,1);
    this.setState({
      list:list
    })
    */
    this.setState((prevState)=>{
      const list = [...prevState.list];
      list.splice(index,1);
      return{list}
    })
  }

}

export default Todolist;
import React, { Component } from 'react'

class TodoItem extends Component {

  constructor(props) {
    super(props);
    this.handleClick=this.handleClick.bind(this);
  }

  render() {
    const {content} = this.props;
    return (
      <div
        onClick={this.handleClick}
        //key={this.props.index}
      >
        {content}
      </div>
    )
  }

  handleClick() {
    const {deleteItem,index} = this.props;
    deleteItem(index);
    //alert(this.props.index);
  }
}

export default TodoItem

三、React开发一些概念

1、声明式开发

(与其对应的是命令式开发,直接操作dom)

我们只是操作数据,React自己操作dom。React是数据驱动的框架,数据变化,页面自动变化。可以减少DOM操作量

2、可以与其他框架并存

只负责自己组件挂载的节点

3、组件化

页面由一个个小组件构成

4、单向数据流

父组件可以向子组件传递数据,但子组件只读不能修改;

子组件可以使用父组件方法改数据。

5、视图层框架

React修改数据可能会很复杂,所以只负责页面,其他工作由其他框架flux,redux等完成

6、函数式编程

使其容易实现前端函数化测试

四、React开发插件安装

1.scientific上网,用Chrome浏览器安装React Developer Tools插件

2.打开页面,该插件灰色表示没用react开发,红色表示处于react开发阶段,黑色表示react编写已在线上状态。

五、传递参数的校验和默认值

propTypes

import PropTypes from 'prop-types'

TodoItem.propTypes = {
  test: PropTypes.string.isRequired, //要求一定检验
  comtent: PropTypes.string,
  deleteItem: PropTypes.func,
  index: PropTypes.number
}

defaultProps

TodoItem.defaultProps = {
  test: 'hello world'
}

参考官网地址:https://reactjs.org/docs/typechecking-with-proptypes.html

六、Props,State 与 render 函数

当组件的state或者props发生改变时,render函数就会重新执行

父组件的render函数被运行时,他的子组件的render都会被重新运行一次

七、什么是虚拟DOM

第一种:

缺陷:

第一次生成了一个完整的DOM片段
第二次生成了一个完整的DOM片段
第二次的DOM替换第一次的DOM,非常耗性能

改良:

缺陷:

性能提升不明显

再改良:

优点:

八、深入理解虚拟DOM

JSX -> JS对象 -> 真实的DOM

JSX -> JS对象实现原理

return <div>item</div>

<=>

return React.createElement('div',{},item)

即:JSX -> createElement -> JS对象

九、虚拟DOM中的Diff算法

<TodoItem 
  key={item}
/>

十、React中ref的使用


  <ul ref={(ul)=>{this.ul = ul}}>
    {this.getTodoItem()}
  </ul>

  handleBtnClick(){
    this.setState((prevState) => ({
      list: [...prevState.list,prevState.inputValue],
      inputValue: ''
    }),()=>{
      console.log(this.ul.querySelectorAll('div').length);
    })
  }

十一、React中的生命周期函数

1. 生命周期函数指在某一时刻组件会自动调用执行的函数。

2. eg:

3. 一些说明

react生命周期.png

(react生命周期.png)

//1.初始化阶段
constructor(){}

//2.挂载阶段
componentWillMount(){} //①在组件即将被挂载到页面的时刻自动执行
render(){} //②挂载页面时执行
componentDidMount(){} //③组件被挂载到页面之后,自动被执行

//3.更新流程
//(1)props发生变化

//一个组件要从父组件接受参娄文
//只要父组件的render函数被重新执行了,子组件的这个生命周期函数就会被执行
componentWillReceiveProps(){} 
shouldComponentUpdate(){return true;//false不更新组件,结束} //组件更新前自动执行
componentWillUpdate(){} //组件更新前shouldComponentUpdate返回true自动执行,返回false不执行
render(){}
componentDidUpdate(){} //组件更新后自动执行

//(2)states发生变化
shouldComponentUpdate(){return true;//false不更新组件,结束} //组件更新前自动执行
componentWillUpdate(){} //组件更新前shouldComponentUpdate返回true自动执行,返回false不执行
render(){}
componentDidUpdate(){} //组件更新后自动执行

//4.卸载阶段
//当这个组件即将被从页面中剔除的时候,会被执行
componentWillUnmount(){}

十二、生命周期函数应用场景

1. shouldComponentUpdate可以避免子组件在父组件更新时重复渲染,实现性能优化,子组件添加如下代码

shouldComponentUpdate (nextProps, nextState) {
  if ( nextProps . content !== this. props. content) {
    return true ;
  }else {
    return false;
  }
}

2. ajax请求放在componentDidMount函数里

yarn add axios #或者 npm install axios -S
import axios from 'axios'

componentDidMount() {
  axios.get('/api/todolist')
    .then(()=>{alert('succ')})
    .catch(()=>{alert('error')})
}

十三、使用Charles进行接口数据模拟

1.install Charles Software

2.use Charles

Tools>Map local>

Map From
Protocol:http
Host:localhost
Port:3000
Path:api/todolist

Map to
Local path:C:\Users\Administrator\Desktop\todolist.json

todolist.json如下

["Dell","Lee","IMOOC"]

<question>不知道为什么Chrome老是获取不到那个json文件,但是QQbrowser却可以。???</question>

十四、引入css样式

部分css代码

.show{
    opacity: 1;
    transition: all 1s ease-in;
}
.hide{
    opacity: 0;
    transition: all 1s ease-in;
}

部分js代码

import './style.css'

  constructor(props){
    super(props);
    this.state = {
      show:true
    };
    this.handleToggle=this.handleToggle.bind(this);
  }

  render() {
    return (
      <div className={this.state.show?'show':'hide'}>hello</div>
      <button onClick={this.handleToggle}>CSStoggle</button><br/>
    )
  }

  handleToggle(){
    this.setState({
      show: this.state.show?false:true
    })
  }
上一篇下一篇

猜你喜欢

热点阅读