反应:即使在调用 setState 后,重新渲染将状态设置为初始值

时间:2021-06-30 22:28:49

标签: javascript reactjs react-hooks setstate

我是 React 的新手,这是我第一次在 StackOverFlow 上提问,所以如果我的问题很蹩脚或者我错过了一些帖子准则,我深表歉意。

我在作为道具传递给子组件的函数中获取 setState 的值:

const [textAreaValue, setTextAreaValue] = useState(null);

const handleTextAreaChange = (newTextAreaValue) => {
        return setTextAreaValue(newTextAreaValue);
    };
  

textAreaValue 不会立即更新,考虑到 React 调度此类请求,这是可以理解的。

我有另一个名为 textFile() 的函数,它在用户单击按钮时触发。

const TextFile = (value) => {
        const element = document.createElement("a");
        console.log(textAreaValue);// outputs null
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };

如评论中所见,状态更新未反映。

要知道状态是否发生变化,我设置了一个 useEffect,并记录了 textAreaValue 的值,它确实显示了更新后的值。

所以我的猜测是,每当重新渲染状态时,状态值都会设置为初始值,即空值。 我在这里摸不着头脑,我真的很想知道这里发生了什么以及我如何解决这个问题。

完整代码如下:

import React, { useEffect, useState } from "react";

import JoditEditor from "../../src/";


const From = () => {
    const [config, setConfig] = useState({
        readonly: false,
        toolbar: true,
        extraButtons: [
            {
                name: "Save to file",
                icon: "fa fa-superscript",
                mode: 3,
                exec: function (a, b, c, d) {
                    debugger;
                    TextFile();
                },
            },
        ],
    });

    const [textAreaValue, setTextAreaValue] = useState(null);
    const _setTextAreaValue = (textval) => {
        setTextAreaValue(textval);
        setTextAreaValue((state) => {
            console.log("after setstate", state); // correct update value;
            return state;
        });
    };
    useEffect(() => {
        //debugger;
        console.log("inside use effect");
        console.log(textAreaValue);
    });

    const TextFile = () => {
        const element = document.createElement("a");
        console.log("inside writetotext", textAreaValue);
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };

    const handleBlurAreaChange = (areaValue, event) => {
        console.log("before handleBlurAreaChange", textAreaValue, event); //null
        _setTextAreaValue(areaValue);
        console.log("after handleBlurAreaChange", textAreaValue); //null
    };

    const handleTextAreaChange = (newTextAreaValue) => {
        //debugger;
        console.log("before handleTextAreaChange", textAreaValue); //null
        _setTextAreaValue(newTextAreaValue);
        console.log(" after handleTextAreaChange", textAreaValue); //null
        return;
    };

    return (
        <div>
            <JoditEditor
                config={config}
                onChange={handleTextAreaChange}
                onBlur={handleBlurAreaChange}
                value={textAreaValue}
            />
        </div>
    );
};

export default From;

0 个答案:

没有答案