无法在异步方法中设置 useState 变量

时间:2021-04-24 17:19:32

标签: javascript reactjs react-native react-hooks

我从 loadFIle 方法中获得了正确的文本。但是当我尝试使用 setCodeToBeDsiplayed 和返回的文本设置状态时,它没有被存储。它在下一行给出空字符串。

const [CodeToBeDsiplayed, setCodeToBeDsiplayed] = useState("")

const [codeVersion, setCodeVersion] = useState(exampleCodeJava8);

 useEffect( () => {
        (async()=>{
            var text=await loadFile(exampleCodeJava8);
            setCodeToBeDsiplayed(text);
            setCodeVersion(CodeToBeDsiplayed);  
        })()
       
    }, [])

loadFile()

async function loadFile(url) {
        console.log("Dowloading file : " + url);

        return new Promise((resolve,reject)=>{
            var json;
            var xhr = new XMLHttpRequest();
            xhr.responseType = 'text';
                xhr.onload =(event)=>{
                    json = xhr.response;
                    console.log("json : " + json);
                    resolve(json);
                };
                xhr.error=(error)=>{
                    reject(error);
                }
            xhr.open('GET', url);
            xhr.send();
        });

3 个答案:

答案 0 :(得分:3)

Michael Parker 的回答 here 应该说明你哪里出错了!

来自 React 的 documentation

<块引用>

setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。

同样,当使用 useState 钩子时,更新不会立即发生,而是排队并创建一个挂起的状态转换。

在您的情况下,您可以使用 - setCodeVersion(text) 来设置您的状态!希望这会有所帮助!

答案 1 :(得分:2)

useState 是一个异步函数,它也不返回 Promise。使用 async/await 或类似的东西是行不通的。您需要使用 useEffect 并添加依赖项来调用要设置的其他状态。

useEffect(() => { setCodeVersion(CodeToBeDsiplayed);}, [CodeToBeDsiplayed])

答案 2 :(得分:1)

你不能在设置它之后获得新的状态值,因为 useState 也是一个 asyc 函数你只需要像 setCodeToBeDsiplayed 一样将相同的文本传递给 setcodeversion 或者你可以这样写

const [CodeToBeDsiplayed, setCodeToBeDsiplayed] = useState("")
const [codeVersion, setCodeVersion] = useState(exampleCodeJava8);
useEffect( () => {
    (async()=>{
        var text=await loadFile(exampleCodeJava8);
        setCodeToBeDsiplayed(text=>{
             setCodeVersion(text);
             return text
         });
    })()
   
}, [])