[英]How to use useState inside useEffect, accessing the updated useState value on component mount?
I'm trying to build a code that can or cannot receive querystrings.我正在尝试构建一个可以或不能接收查询字符串的代码。 If it receives all querystrings, I want to execute a function:
如果它接收到所有查询字符串,我想执行一个 function:
// state for query
const [query, setQuery] = useState({
periodicity: "",
stock: "",
date: moment().subtract(1, "y"),
investment: ""
});
// check if there are query strings
function useQuery() {
return new URLSearchParams(useLocation().search);
}
let qs = useQuery();
let queries = {};
// set query strings received
useEffect(() => {
if (qs.has("periodicity")) {
queries.periodicity = qs.get("periodicity");
}
if (qs.has("start_date")) {
queries.date = moment(qs.get("start_date"));
}
if (qs.has("symbol")) {
queries.stock = { value: qs.get("symbol"), label: qs.get("symbol") };
}
if (qs.has("investment")) {
queries.investment = qs.get("investment");
}
setQuery({ ...query, ...queries });
if (
query.periodicity !== "" &&
query.stock !== "" &&
query.investment !== ""
) {
simulate();
}
}, []);
The initial state
is the query
state. initial state
是query
state。 What I'm doing is, on component mount, verify if there are query strings and change the component to match the query strings received.我正在做的是,在组件挂载时,验证是否有查询字符串并更改组件以匹配收到的查询字符串。
The problem is, I never enter the last if (query.periodicity.== "" && query.stock !== "" && query.investment !== "")
.问题是,我从不输入最后一个
if (query.periodicity.== "" && query.stock !== "" && query.investment !== "")
。 I know it's because useState
will update the state on the next component mount, and that useEffect
is only running once, before useState
updates the state.我知道这是因为
useState
将在下一个组件安装时更新 state,并且useEffect
只运行一次,然后useState
更新 state。 But how can I fix it without entering in a loop?但是如何在不进入循环的情况下修复它?
I can't put the query
in the useEffect
dependency array, because if the user fills all data and the query
state becomes populated, I don't want to automatically run the simulate()
function, because the user needs to click on a button.我不能把
query
放在useEffect
依赖数组中,因为如果用户填写了所有数据并且query
state 被填充,我不想自动运行simulate()
function,因为用户需要点击一个按钮. I just want to run it automatically if I received all the query strings needed when entering this page.如果我收到进入此页面时所需的所有查询字符串,我只想自动运行它。
Thanks in advance!提前致谢!
You can set the state in the component function body and check it in the useEffect
callback:您可以在组件 function 主体中设置 state 并在
useEffect
回调中检查它:
function App(props) {
const initialState = {
periodicity: "",
stock: "",
date: "2019-01-01",
investment: ""
};
let qs = useQuery();
let queries = {};
if (qs.has("periodicity")) {
queries.periodicity = qs.get("periodicity");
}
if (qs.has("start_date")) {
queries.date = qs.get("start_date");
}
if (qs.has("symbol")) {
queries.stock = { value: qs.get("symbol"), label: qs.get("symbol") };
}
if (qs.has("investment")) {
queries.investment = qs.get("investment");
}
const [query, setQuery] = useState(
receivedQueryString(queries) ? queries : initialState
);
/*
* Rest of the component implementation
*/
function receivedQueryString(query) {
return (
query.periodicity != "" && query.stock != "" && query.investment != ""
);
}
useEffect(() => {
if (receivedQueryString(query)) {
simulate();
}
});
function simulate() {
props.history.push(
`/?periodicity=${query.periodicity}&start_date=${query.date}&symbol=${
query.stock.value
}&investment=${query.investment}`
);
// calls API
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.