• react ant design Select defaultValue 属性失效


    1. 场景描述

    在做个人项目的时候, 发现了一个问题: ant design UI 框架中, Select 组件的 defaultValue 属性失效了, 即设置了defaultValue 值缺没有默认的选定内容;

    上面这个问题可以抽象成为如下沙盒:
    PS: 该沙盒最好在codesandbox 网站下运行

    import React from "react";
    import { Select } from 'antd';
    const { Option } = Select;
    
    import 'antd/dist/antd.css'
    
    const log = console.log.bind(console)
    
    class App extends React.Component{
        constructor(props) {
            super(props)
            this.state = {
              
            }
        }
    
        // 1. 当生命周期函数为componentDidMount 时, 执行的顺序应该为:
        // constructor -> render -> componentDidMount -> render;
        // 而控制台显示执行了4次render, 这是为什么? 
        
        // 2. 当生命周期函数为componentDidMount 时, 在最后一次执行render时, 
        // defaultValue 属性已经被赋值为here, 为什么这个属性没有效果
        // componentDidMount() {
        // this.setState({
        // defaultValue: 'here'
        // })
        // }
    
        // 3. 当生命周期函数为componentWillMount 时, 执行的顺序为:
        // constructor -> componentWillMount -> render(加载过程默认的)-> render(this.setData 更新过程触发的);
        // 那么为什么两次控制台输出都是here, 这是由于consolo.log 的限制造成的吗?
        // componentWillMount() {
        // this.setState({
        // defaultValue: 'here'
        // })
        // }
    
        
        render() {
          let {defaultValue} = this.state
          log('执行了render 函数 defaultValue = ', String(defaultValue))
          return (
              <>
                <Select value={defaultValue} style={{  120 }}>
                  <Option value="jack">Jack</Option>
                  <Option value="lucy">Lucy</Option>
                  <Option value="here">
                    here
                  </Option>
                  <Option value="Yiminghe">yiminghe</Option>
                </Select>
              </>
          )
        }
    }
    
    export default App
    

    2. 问题描述即解答

    2.1 组件渲染两次?

    当生命周期函数为componentDidMount 时, 执行的顺序应该为: constructor -> render -> componentDidMount -> render; 而控制台显示执行了4次render, 这是为什么?

    运行结果:

    上面的沙盒(demo)运行环境为: codesandbox, 如果是在本地自建React 项目, 将不会运行4次, 而应该是2次

    因为 React 在 Dev mode 下会刻意执行两次渲染,以防止组件内有什么 side effect 引起 bug,提前预防; 详细内容可以参见如下地址: 为什么 react 的函数组件每次渲染执行两次?

    2.2 ant design Select defaultValue 属性失效

    当生命周期函数为componentDidMount 时, 在最后一次执行render时, defaultValue 属性已经被赋值为here, 为什么这个属性没有效果

    因为组件第一次加载的时候会取defaultValue,之后重新渲染将不会处理defaultValue。如果重新渲染组件时, 还需要加载默认值, 则使用value 属性; 详细内容可以参见如下地址: ant design Select API

    其实这个严格上来说是自己没有好好看文档, 先入为主了.

    2.3 componentWillMount 生命周期

    当生命周期函数为componentWillMount 时, 执行的顺序为: constructor -> componentWillMount -> render(加载过程默认的)-> render(this.setData 更新过程触发的);那么为什么两次控制台输出都是here, 这是由于consolo.log 的限制造成的吗?

    首先输出两次的原因是因为组件渲染了两次, 这个可以参考第一个问题;

    当生命周期函数为componentWillMount 时, 如果在componentWillMount 生命周期中使用this.setData, 此时this.setData 是一个同步函数, 而非异步函数, 因此render 中defaultValue 的值为 here

    值得说明的是 componentWillMount 该生命周期函数已不被官方所推荐, 因此尽量不要使用. 具体内容可以参考如下地址: React 官方文档

    this.props 数据应该只在子组件负责渲染; this.props 数据更改应该发生在父组件, 这样更符合生命周期设计(componentWillReceiveProps生命周期方法已不被官方推荐

    3. 参考链接

    1. 为什么 react 的函数组件每次渲染执行两次?
    2. ant design Select API
    3. React 官方文档
  • 相关阅读:
    ORACLE11G 字符集更改(这里更改为AL32UTF8)
    linux 安装jdk1.8
    oracle的 listagg() WITHIN GROUP ()函数使用
    数据库事务中的隔离级别和锁以及spring @Transactional注解参数详解
    java读取Oracle中大字段数据(CLOB)的方法
    oracle常用函数_时间
    案例-todolist计划列表【添加计划】
    案例-todolist计划列表【显示列表】
    案例-todolist计划列表[基本代码]
    vue 阻止元素的默认行为
  • 原文地址:https://www.cnblogs.com/oulae/p/13035516.html
Copyright © 2020-2023  润新知