• React 学习笔记


    声明式的开发 React
    命令式的开发 Jquery


    单项数据流
    父组件可以给子组件传值,但子组建不能改变这个值
    单项数据流的好处:
    实际是为了开发时方便,不容易遇到坑,方便测试。
    一个父子建有五个子组件,假如没有单项数据六的概念,任何一个子组件把父组件给改变了(删除等),其余的几个组建也会受到影响。


    视图层框架

    数据层框架

    函数式编程

    TodoList.js中的文件

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

    // import { Component } from 'react';
    // import React from 'react'
    // const Component = React.Component


    // Fragment 代替div


    class TodoList extends Component {

      constructor(props){
        super(props); //继承
        // 组建的状态
        this.state = {
          inputValue: '',
          list: ['1','2'],
        }
        this.handleInputChange = this.handleInputChange.bind(this)
      }

      

      //在组件即将被挂载在页面的时刻自动执行
      componentWillMount(){
        console.log('componentWillMount')
      }

      render() {
        return (

          <Fragment>
            <div>
              {/*下面时一个input框*/}
              {
                //下面时一个input框
              }
              <label htmlFor="insertArea">输入内容</label>
              <input
                id='insertArea'
                className='input'
                value={this.state.inputValue} type=""
                onChange={this.handleInputChange}
                ref={(input) => {this.input = input}}
              />
              <button onClick={this.handleBtnClick.bind(this)}>提交</button>
            </div>
            <ul ref={(ul) => {this.ul=ul}}>
              { this.getTodoItem() }
            </ul>
            <Test content={ this.state.inputValue } />
          </Fragment>
        );
      }

      

      

      //在组件挂载在页面的完毕时刻自动执行
      componentDidMount(){
        console.log('componentDidMount')
      }

      //组件更新之前,他会自动被执行==你的组件需要被更新?决定组件是否要被更新
      shouldComponentUpdate(){
        console.log('shouldComponentUpdate')
        return true
      }

      //组件被更新之前,他会自动执行,但是他在shouldComponent之后被执行,、
      //如果shouldComponentUpdate返回true才执行
      //如果shouldComponentUpdate返回false不执行
      componentWillUpdate(){
        console.log('componentWillUpdate')
      }
      //组件更新完成之后会被执行
      componentDidUpdate(){
        console.log("componentDidUpdate")
      }

      getTodoItem() {
        return this.state.list.map((item,index)=>{
          return (
            <div key={index}>
              <TodoItem
                content={item}
                index={index}
                deleteItem = {this.handleItemDelete.bind(this)}
              />
              {/*<li
                key={index}
                onClick={this.handleItemDelete.bind(this,index)}
                dangerouslySetInnerHTML={{ __html:item }}
              >
              </li>*/}
            </div>

          )
        })
      }

      handleInputChange(e){
        console.log(this.input.value)

        //react最新版本的改变状态的写法
        const value = e.target.value
        this.setState( () => ({
          inputValue: value
        }))


        // this.setState({
          // inputValue: e.target.value
        // })
      }
      handleBtnClick(){
        // 异步
        this.setState( (prevState) => ({
          // prevState之前的数据
          list: [...prevState.list,prevState.inputValue],
          inputValue: ''
        }),() => {
          console.log(this.ul.querySelectorAll('div').length)
        })

        // console.log(this.ul.querySelectorAll('div').length)

        // this.setState({
          // list: [...this.state.list,this.state.inputValue],
          // inputValue: ''
          // })
      }
      handleItemDelete(index){
        // immutable
        // state 不允许我们做任何改变
        // const list = [...this.state.list]

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


        // this.setState({
          // list: list
        // })
      }

    }

    export default TodoList;

    TodoItem.js

    import React,{ Component } from 'react';
    import PropTypes from 'prop-types';

    class TodoItem extends Component{

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

      // 使用 shouldComponentUpdate优化性能,不需要input输入值改变就重新渲染子组件,做个判断
      shouldComponentUpdate(nextprevProps,nextState){
        console.log(nextprevProps,nextState)
        if(nextprevProps.conent !== this.props.conent){
          return true
        }else{
          return false
        }
      }

      render(){
        const { content, test } = this.props
        return (

          <div
            key={this.props.index}
            onClick={this.handleClick}
          >
            {/*React.createElement('div',{},'item')*/}
            { test } - { content }
          </div>
        )
      }

      //当一个组件从父组件接收了参数
      //只要父组件的render函数执行了,子组件的这个生命周期函数就会被执行
      //如果这个组件第一年存在于父组件中,不会执行
      //如果这个组件之前已经存在于父组件中,会被执行
      componentWillReceiveProps(){
        console.log("child componentWillReceiveProps")
      }

      //当这个组件即将被从页面剔除的时候,会被执行
      componentWillUnmount(){
        console.log("child componentWillUnmount")
      }

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

    //属性校验==要求父组件给子组件传值的校验
    // isRequired 必须要传值
    TodoItem.propTypes = {
      test: PropTypes.string.isRequired,
      content: PropTypes.oneOfType([PropTypes.string,PropTypes.number]),
      deleteItem: PropTypes.func,
      index: PropTypes.number,
    }


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

    export default TodoItem

    Test.js

    import React,{ Component } from 'react';

    class Test extends Component{
      render () {
        return <div>{ this.props.content }</div>
      }
    }


    export default Test

    propTypes 与 DefaultProps
    //属性校验==要求父组件给子组件传值的校验
    TodoItem.propTypes = {
    content: PropTypes.string,
    deleteItem: PropTypes.func,
    index: PropTypes.number
    }
    // 默认复制
    TodoItem.defaultProps = {
    test: 'hello world'
    }


    Props,State与render函数
    当数据发生变化时,页面就跟着发生变化
    当组件的state或者props发生改变的时候,render函数就会重新执行;
    当父组件的render函数被运行时 ,他的子组件的render都将被重新运行一次

    什么是虚拟DOM?


    原始操作的方法
    1. state 数据
    2. jsx 模板
    3. 数据 + 模板 结合,生成真是的DOM,来显示
    4. state 发生改变
    5. 数据 + 模板 结合,生成真是的DOM,替换原始的DOM

    缺陷:
    第一次生成了一个完成额DOM片段
    第二次又生成了一个完成的DOM片段
    第二次的DOM替换第一次的DOM,非常好性能


    1. state 数据
    2. jsx 模板
    3. 数据 + 模板 结合,生成真是的DOM,来显示
    4. state 发生改变
    5. 数据 + 模板 结合,生成真是的DOM,并不直接替换原始的DOM
    6. 新的DOM和原始的DOM作比对,找差异
    7. 找出input框发生了变化
    8. 只用新的DOM中的input元素,替换掉老的DOM中的input元素

    缺陷:
    性能的提升并不明显

    React引入的虚拟DOM提高性能的方式
    1. state 数据
    2. jsx 模板
    3. 数据 + 模板 生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真是的DOM)(损耗了性能)
    ['div',{id:'abc'},['span',{},"hello world"]]
    4. 用虚拟dom的结构生成真是的DOM,来显示
    <div id="abc"><span>hello world</span></div>
    5. state 发生变化
    <div id="abc"><span>bye bye</span></div>
    6. 数据+模板 生成虚拟DOM(极大的提升了性能)
    ['div',{id:'abc'},['span',{},"bye bye"]]
    7. 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(极大的提升了性能)
    diff
    setState 异步算法,提高了比对。
    8. 直接操作DOM,改变span中的内容

    有点:
    1.性能提升了
    2.他使得跨端应用得以实现。 React Native


    //深入了解虚拟DOM

    //虚拟DOM中的DIff算法


    //React 中的ref的使用

    React中的生命周期函数
    //生命周期函数指在某一时刻组件会自动执行的函数

    //在组件即将被挂载在页面的时刻自动执行
    componentWillMount(){
      console.log('componentWillMount')
    }

    //在组件挂载在页面的完毕时刻自动执行
    componentDidMount(){
    console.log('componentDidMount')
    }

    //组件更新之前,他会自动被执行==你的组件需要被更新?
    shouldComponentUpdate(){
      console.log('shouldComponentUpdate')
      return true
    }

    //组件被更新之前,他会自动执行,但是他在shouldComponent之后被执行,、
    //如果shouldComponentUpdate返回true才执行
    //如果shouldComponentUpdate返回false不执行
    componentWillUpdate(){
      console.log('componentWillUpdate')
    }
    //组件更新完成之后会被执行
    componentDidUpdate(){
      console.log("componentDidUpdate")
    }

    //当一个组件从父组件接收了参数
    //只要父组件的render函数执行了,子组件的这个生命周期函数就会被执行
    //如果这个组件第一年存在于父组件中,不会执行
    //如果这个组件之前已经存在于父组件中,会被执行
    componentWillReceiveProps(){
      console.log("child componentWillReceiveProps")
    }

    //当这个组件即将被从页面剔除的时候,会被执行
    componentWillUnmount(){
      console.log("child componentWillUnmount")
    }

  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/sklhtml/p/9518171.html
Copyright © 2020-2023  润新知