Javascript 在状态更改之前运行代码
我是React和ES6的新手,我有这样一个组件: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
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?