在React開發中遇到的問題——數組引用賦值


在React開發中遇到了一個問題:
需求是在一個選擇組件中選擇數據mydata數組,確定后將mydata數組返回到父組件,再次打開該選擇組件時,從父組件獲取之前選擇的數據mydata並顯示為已選擇。

    /* 打開選擇組件 */
    showModal = () => {
        this.setState({
            comVisible: true
        });
        const { mydata } = this.props;
        this.setState({
            mydata: mydata
        });
        console.log(this.state.mydata);
        this.onChange();
    }

    /* 確定-將data返回父組件 */
    handleOk = () => {
        if (this.state.mydata.length > 0) {
            this.setState({
                comVisible: false
            });
            // 返回父組件data
            this.props.getMyData({
                mydata: this.state.mydata,
                ...
            });
        } else {
            message.error("data is null");
        }
    }

    /* 取消-不對data做操作 */
    handleCancel = () => {
        this.setState({
            comVisible: false
        });
    }
    /* 選擇data */
    onChange = (mydata) => {
        let mydata = this.state.mydata;
        Object.keys(otherdata).forEach((title) => {
           ... 
           // 對mydata做一些改變
        });
        this.setState({
            mydata
        });
    }

大概流程如下:
流程.png

按照邏輯,在選擇組件中選擇mydata,觸發onChange事件,將此時改變的mydata設置為state.mydata,點擊確定后觸發handleOk函數,將state.mydata傳給父組件。但若點擊取消,則觸發handleCancel,不做任何操作。
那么問題來了,我點擊了取消,再次打開選擇組件,從父組件取mydata的值,取到的是點擊取消之前選擇的mydata值。按理說點擊了取消不做操作,該值是不會傳給父組件的,但是為什么從父組件會取到改變后的值呢?

經過一系列嘗試后發現,問題的原因在於數組的表現形式就是內存中的一段連續的內存地址,數組名稱其實就是連續內存地址的首地址。onChange中對mydatastate.mydata的改變會直接改變該數組所指向的地址中的數據,而父組件中的mydata也是指向該數組的,所以一旦state.mydata發生改變,即使不將改變后的mydata傳給父組件,父組件的mydata也會改變。

修改:給父組件傳值時使用中間變量,並且數組賦值時,使用先結構再賦值的方式生成新的數組。

    /* 打開選擇組件 */
    showModal = () => {
        this.setState({
            comVisible: true
        });
        const { mydata } = this.props;
        this.setState({
            mydata: mydata
        });
        this.onChange();
    }

    /* 確定-將data返回父組件 */
    handleOk = () => {
        if (this.state.mydata.length > 0) {
            // 返回父組件data,改變后的中間變量
            this.props.getMyData({
                mydata: this.state.tempdata,
                ...
            });
        } else {
            message.error("data is null");
        }
    }

    /* 取消-不對data做操作 */
    handleCancel = () => {
        ...
    }
    /* 選擇data */
    onChange = (mydata) => {
        // 改變賦值方式
        let mydata = [];
        mydata.push(...this.state.mydata);
        Object.keys(otherdata).forEach((title) => {
           ... 
           // 對mydata做一些改變
        });
        // 使用中間變量,不直接修改state.mydata
        this.setState({
            tempdata: mydata
        });
    }

總結:

在JS中,
數組和對象是地址型變量
數組和對象是地址型變量
數組和對象是地址型變量

基礎知識一定時刻記在腦子里。。。


免責聲明!

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



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