Javascript 在状态更改之前运行代码

Javascript 在状态更改之前运行代码,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我是React和ES6的新手,我有这样一个组件: import React, { useState } from 'react'; const Order = () => { let username='Test',password = 'secret'; const [Data,setData]=useState({title:'',submit:false}); const [List,setList]=useState({title:'',submit:fa

我是React和ES6的新手,我有这样一个组件:

import React, { useState } from 'react';

const Order = () => {
    let username='Test',password = 'secret';
    const [Data,setData]=useState({title:'',submit:false});
    const [List,setList]=useState({title:'',submit:false});
    const Clicked = ()=>{
        if(username==='Test'){
            setData({title:'Yes',submit:true});
        }
        else{
            setData({title:'No',submit:false});
        }
        if(password==='secret'){
            setList({title:'Yes',submit:true});
        }
        else{
            setList({title:'No',submit:false});
        }
        console.log(Data.submit,List.submit);
        if(Data.submit && List.submit){
            alert('Time to Submit')
        }
    }
    return (
        <div>
            <button onClick={Clicked}>Click</button>
        </div>
    );
}
 
export default Order;
我的问题是,当我单击按钮时,Data.submit和List.submit在第一次单击时都被视为False,但在第二次单击时,它们都变为true,并发出“提交时间”警报。 因为我正在为两个不同的按钮使用数据和列表,所以不能使用useEffect。
我不希望用户单击两次。我如何才能做到这一点?

setState is asynchronous React将决定何时应用更改以提高性能,在您登录控制台时,状态尚未更改。如果不想使用useEffect来检测状态何时更改,可以使用函数中已有的变量

const Order = () => {
  let username = "Test",
    password = "secret";
  const [Data, setData] = useState({ title: "", submit: false });
  const [List, setList] = useState({ title: "", submit: false });
  const Clicked = () => {
    let dataSubmit, listSubmit;
    if (username === "Test") {
      dataSubmit = true;
      setData({ title: "Yes", submit: true });
    } else {
      setData({ title: "No", submit: false });
    }
    if (password === "secret") {
      listSubmit = true;
      setList({ title: "Yes", submit: true });
    } else {
      setList({ title: "No", submit: false });
    }
    if (dataSubmit && listSubmit) {
      alert("Time to Submit");
    }
  };
  return (
    <div>
      <button onClick={Clicked}>Click</button>
    </div>
  );
};

    const Clicked = ()=>{
        if(username==='Test'){
            setData({title:'Yes',submit:true});
        }
        else{
            setData({title:'No',submit:false});
        }
        if(password==='secret'){
            setList({title:'Yes',submit:true});
        }
        else{
            setList({title:'No',submit:false});
        }
        if(username==='Test' && password==='secret'){
            alert('Time to Submit')
        }
    }

setState is asynchronous React将决定何时应用更改以提高性能,当您登录到控制台时,状态尚未更改。如果不想使用useEffect来检测状态何时更改,可以使用函数中已有的变量

    const Clicked = ()=>{
        if(username==='Test'){
            setData({title:'Yes',submit:true});
        }
        else{
            setData({title:'No',submit:false});
        }
        if(password==='secret'){
            setList({title:'Yes',submit:true});
        }
        else{
            setList({title:'No',submit:false});
        }
        if(username==='Test' && password==='secret'){
            alert('Time to Submit')
        }
    }

这主要是因为set状态是异步的,因此如果像同步代码一样调用,它将无法按预期工作

要解决此问题,可以执行以下操作:

从“React”导入React,{useState}; 常量顺序==>{ 让username='Test',password='secret'; const[Data,setData]=useState{title:,submit:false}; const[List,setList]=useState{title:,submit:false}; 常量单击==>{ const data={title:,submit:false}; const list={title:,submit:false}; ifusername=='Test'{ data.title='是'; data.submit=true; } 否则{ data.title='否'; data.submit=false; } ifpassword==='secret'{ list.title='是'; list.submit=true; } 否则{ list.title='No'; list.submit=false; } console.logData.submit,List.submit; ifdata.submit&&list.submit{ 提醒“提交时间” } setDatadata; 集合列表; } 回来 点击 ; }
导出默认订单 这主要是因为set状态是异步的,因此如果像同步代码一样调用,它将无法按预期工作

要解决此问题,可以执行以下操作:

从“React”导入React,{useState}; 常量顺序==>{ 让username='Test',password='secret'; const[Data,setData]=useState{title:,submit:false}; const[List,setList]=useState{title:,submit:false}; 常量单击==>{ const data={title:,submit:false}; const list={title:,submit:false}; ifusername=='Test'{ data.title='是'; data.submit=true; } 否则{ data.title='否'; data.submit=false; } ifpassword==='secret'{ list.title='是'; list.submit=true; } 否则{ list.title='No'; list.submit=false; } console.logData.submit,List.submit; ifdata.submit&&list.submit{ 提醒“提交时间” } setDatadata; 集合列表; } 回来 点击 ; }
导出默认订单 根据我的直觉,useState回调是异步的,这就是为什么日志输出数据的未更改版本@Nishant上面的解决方案应该可以很好地工作。

根据我的直觉,useState回调是异步的,这就是为什么日志输出数据的未更改版本@Nishant上面的解决方案应该很好。

这是我提出的解决方案,我添加了一些评论来说明,我有任何问题,请不要犹豫问我。另外,我不是以英语为母语的人,因为我的英语很抱歉

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

    const Order = () => {
        let username='Test',password = 'secret';
        //fist of all, I recomend you to call your useState variables
        //always using lowercase becase if you name it uppercase
        //it means that is a component o a class
        const [data, setData]=useState({title:'',submit:false});
        const [list, setList]=useState({title:'', submit:false});

        //I also recomment to call you functions using camelCase using the first letter with lowercase
        const clicked = ()=>{
          // I created a couple variables to improve readability and help with logic
          const correctUsername = username === 'Test' //this will return true if username equal test, otherwise will return false;
          const correctPassword = password === 'secret'; //same here

          //Here, you can use a ternary, that is the same as is else, but in a short way
          // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
          setData(correctUsername ? {title: 'Yes', submit: true} : {title: 'No', submit: false});
          setList(correctPassword ? {title: 'Yes', submit: true} : {title: 'No', submit: false});
        }

        
    //You can use an useEffect to watch stateChanges
        useEffect(()=>{
          if(data.submit && list.submit){
            console.log({data, list})
            alert('Time to Submit')
            }
          },[data, list]) 

        return (
            <div>
                <button onClick={clicked}>Click</button>
            </div>
        );
    }
    
    export default Order;

这就是我提出的解决方案,我添加了一些评论来说明问题,如果你有任何问题,请毫不犹豫地问我。另外,我不是以英语为母语的人,因为我的英语很抱歉

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

    const Order = () => {
        let username='Test',password = 'secret';
        //fist of all, I recomend you to call your useState variables
        //always using lowercase becase if you name it uppercase
        //it means that is a component o a class
        const [data, setData]=useState({title:'',submit:false});
        const [list, setList]=useState({title:'', submit:false});

        //I also recomment to call you functions using camelCase using the first letter with lowercase
        const clicked = ()=>{
          // I created a couple variables to improve readability and help with logic
          const correctUsername = username === 'Test' //this will return true if username equal test, otherwise will return false;
          const correctPassword = password === 'secret'; //same here

          //Here, you can use a ternary, that is the same as is else, but in a short way
          // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
          setData(correctUsername ? {title: 'Yes', submit: true} : {title: 'No', submit: false});
          setList(correctPassword ? {title: 'Yes', submit: true} : {title: 'No', submit: false});
        }

        
    //You can use an useEffect to watch stateChanges
        useEffect(()=>{
          if(data.submit && list.submit){
            console.log({data, list})
            alert('Time to Submit')
            }
          },[data, list]) 

        return (
            <div>
                <button onClick={clicked}>Click</button>
            </div>
        );
    }
    
    export default Order;
那我们回拨呢?还有,为什么不能使用useEffect?useCallback呢?还有,为什么不能使用useEffect?