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={{ width: 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 官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM