React基础知识,一篇文章搞懂,包含state,props,ref,受控组件与非受控组件,函数柯里化,React生命周期(新旧)


react的语法是jsx,下面是jsx语法规范
在这里插入图片描述

State

函数组件没有state

类组件第一种写法

class Home extends React.Component{
    constructer(props){
        super(props)
        this.state = {
            name: '王狗剩'
        }
    }
}

类组件语法糖

// 可以不写constructer、super
class Home extends React.Component{
    state = {
        name: '王狗剩'
    }
}

点击事件修改state中的属性

不可以使用this.state.属性名直接修改,必须使用setState({ })的方式来修改

class Home extends React.Component{
    state = {
        name: '王狗剩'
    }
    render(){
        return (
            <div onClick={this.changeState}>点击修改state</div>
        )
    }
    changeState = () => {
        this.setState({
            name: '李翠花'
        })
    }
}

Props

类组件

props依赖下载: 主要用于定义传值的数据类型默认数据

//npm
npm install --save prop-types

//Importing
import PropTypes from 'prop-types'; // ES6

// 所有类型如下
  // optionalArray: PropTypes.array,
  // optionalBool: PropTypes.bool,
  // optionalFunc: PropTypes.func,
  // optionalNumber: PropTypes.number,
  // optionalObject: PropTypes.object,
  // optionalString: PropTypes.string,
  // optionalSymbol: PropTypes.symbol,

// 定义props的类型,必要性
Home.propsTypes = {
    name: PropTypes.string.Required   // after and type 默认必填
}

// 定义props的默认值
Home.defaultProps = {
  name: 'default',  // 如果不填的话name的默认值,和Required冲突
}

常用的写法

class Home extends React.Component {
    // static 静态
    static propsTypes = {
        name: PropTypes.string.Required   // after and type 默认必填
    }
    static defaultProps = {
      name: 'default',  // 如果不填的话name的默认值,和Required冲突
    };
    render() {}
  }

函数式组件

function Home(props){   // 传值
    return (
        <div>{props.name}</div>
    )
}

// 定义props的类型,必要性
Home.propsTypes = {
    name: PropTypes.string.Required   // after and type 默认必填
}

// 定义props的默认值
Home.defaultProps = {
  name: 'default',  // 如果不填的话name的默认值,和Required冲突
}

ref

// 已弃用
class Home extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.handler}>点击按钮</button>
        <div ref="box1">{this.props.name}</div>
      </div>
    );
  }
  handler= () => {
    console.log(this.refs.box1);
  };
}

目前新版本使用回调的refs

// 如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,
// 所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
class Home extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.handler}>点击按钮</button>
        <div ref={c=>{this.box = c}>{this.props.name}</div>
      </div>
    );
  }
  handler= () => {
    console.log(this.box);
  };
}

// 这样写就行了
class Home extends React.Component {
  saveBox = (c) => {
      this.box = c
  }
  render() {
    return (
      <div>
        <button onClick={this.handler}>点击按钮</button>
        <div ref={this.saveBox}>{this.props.name}</div>
      </div>
    );
  }
  handler= () => {
    console.log(this.box);
  };
}

// 官方最推荐的ref方式
class Home extends React.Component {
  myRef = React.createRef()
  render() {
    return (
      <div>
        <button onClick={this.handler}>点击按钮</button>
        <div ref={this.myRef}>{this.props.name}</div>
      </div>
    );
  }
  handler= () => {
    console.log(this.myRef.current);
  };
}

受控组件与非受控组件

// 例如在表单中输入时将数据管理的状态中的组件叫受控组件
// 在表单点击提交直接通过ref拿到数据并提交的组件叫非受控组件

在受控组件中使用函数柯里化

class Home extends React.Component {
  state = {
    username: '',
    password: '',
  };
  render() {
    return (
      <div>
        <form action="#">
          <input onChange={this.saveFormData('username')} type="text" />
          <input onChange={this.saveFormData('password')} type="password" />
        </form>
      </div>
    );
  }
  saveFormData = (dataType) => {  // 通过函数调用继续返回函数的方式,实现多次接受参数统一处理的函数编码形式叫函数柯里化
    return (e) => {
      // console.log(e.target.value);
      // console.log(dataType);
      this.setState({
        [dataType]: e.target.value,
      });
    };
  };
}

在受控组件中不使用函数柯里化

class Home extends React.Component {
  state = {
    username: '',
    password: '',
  };
  render() {
    return (
      <div>
        <form action="#">
          <input onChange={(event) => { this.saveFormData('username', event.target.value);}} type="text" />
          <input onChange={(event) => {this.saveFormData('password', event.target.value);}} type="password" />
        </form>
      </div>
    );
  }
}

React生命周期(旧)

第一阶段,初始化阶段,由ReactDOM.render()触发,初次渲染

constructor(){} =====> 构造器
componentWillMount(){} =======> 组件挂载之前
render(){} ======> 挂载结构
componentDidMount(){} =======> 组件挂载后
    >>>>>>>常用钩子,一般用来做一些初始化的事情:开启定时器,发送网络请求,订阅消息

第二阶段,更新阶段,由内部this.setState()或父组件render()触发

shouldComponentUpdate() { =======> 组件是否被更新
    return false;
}
componentWillUpdate(){} =======> 组件更新前
render(){} ======> 挂载结构
componentDidUpdate(){} =======> 组件更新后

第三阶段,卸载阶段,由ReactDOM.unmountComponentAtNode()触发

componentWillUnmount(){} =======> 组件卸载之前
    >>>>>>>常用钩子,一般用来做一些收尾事情:关闭定时器,取消订阅消息

所有阶段展示

更新条件
1.setState() // 修改数据时触发更新
2.forceUpdate() // 强制更新,不经过shouldComponentUpdate(){}
3.componentWillReceiveProps(){} // 父组件更新引发更新

constructor(){} =====> 构造器
componentWillMount(){} =======> 组件挂载之前
render(){} ======> 挂载结构
componentDidMount(){} =======> 组件挂载后
componentWillUnmount(){} =======> 组件卸载之前

shouldComponentUpdate() { return false } =======> 组件是否被更新

componentWillUpdate(){} =======> 组件更新前
componentDidUpdate(){} =======> 组件更新后

React生命周期(新)

第一阶段,初始化阶段,由ReactDOM.render()触发,初次渲染

constructor(){} =====> 构造器
getDerivedStateFromProps() {}  =====> 从Props获取派生
render(){} ======> 挂载结构
componentDidMount(){} =======> 组件挂载后

第二阶段:更新阶段,由内部this.setState()或父组件render()触发

getDerivedStateFromProps() {}  =====> 从Props获取派生
shouldComponentUpdate() { return false } =======> 组件是否被更新
render(){} ======> 挂载结构
getSnapshotBeforeUpdate(prevProps, prevState) {} ======> // 获取快照更新前
componentDidUpdate(){} =======> 组件更新后

第三阶段:卸载阶段,由ReactDOM.unmountComponentAtNode()触发

componentWillUnmount(){} =======> 组件卸载之前

总结:

废弃了三个will

UNSAFE_componentWillMount() {} =====> 挂载前
UNSAFE_componentWillUpdate() {} =====> 更新前
UNSAFE_shouldComponentUpdate() { return false } =======> 组件是否被更新

新增了两个get

getDerivedStateFromProps(props, state) {} // 从Props获取派生

此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。例如,实现 组件可能很方便,该组件会比较当前组件与下一组件,以决定针对哪些组件进行转场动画。
派生状态会导致代码冗余,并使组件难以维护。 确保你已熟悉这些简单的替代方案:

getSnapshotBeforeUpdate(prevProps, prevState) {   // 获取快照更新前
    return '123'  // 这个值将返回给componentDidMount(){} 钩子函数的第三个参数,第一个:先前的props,第二个:先前的state,第三个:return的值
}
// 可用于固定滚动条的位置,

详情请看官网:
点击跳转官网,查看新增生命周期详情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值