【问题标题】:React: Re-render sets state to initial value even after calling setState反应:即使在调用 setState 之后,重新渲染也会将状态设置为初始值
【发布时间】:2021-06-30 22:28:49
【问题描述】:

我是 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 的值,它确实显示了更新后的值。

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

这是完整的代码:

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;

【问题讨论】:

    标签: javascript reactjs react-hooks setstate


    【解决方案1】:

    对于下面函数内部的参数:

    const _setTextAreaValue = (textval)
    

    您可以尝试如下更改吗:

    const _setTextAreaValue = (e) => {
    setTextAreaValue(e.target.value)
    console.log(textAreaValue)
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-09
      • 1970-01-01
      • 2020-02-18
      • 2019-03-05
      • 1970-01-01
      • 2019-12-13
      • 1970-01-01
      • 2022-11-04
      • 2019-08-04
      相关资源
      最近更新 更多