如何在useEffect中使用useState,在组件安装时访问更新的useState值?

时间:2019-11-04 14:36:12

标签: javascript reactjs

我正在尝试建立一个可以或不能接收查询字符串的代码。如果接收到所有查询字符串,我要执行一个函数:

Matcher matcher = pattern.matcher("111111111111111122);

 while (matcher.find()) {
   System.out.println(matcher.group());
}

// 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(); } }, []); initial state状态。我正在做的是,在组件安装上,验证是否存在查询字符串,并更改组件以匹配收到的查询字符串。

问题是,我从未输入最后一个query。我知道这是因为if (query.periodicity !== "" && query.stock !== "" && query.investment !== "")将在下一次组件安装时更新状态,并且useState仅运行一次,然后useEffect更新状态。但是,如何在不进入循环的情况下进行修复?

我无法将useState放入query依赖项数组中,因为如果用户填充了所有数据并且填充了useEffect状态,我就不想自动运行query功能,因为用户需要单击按钮。如果进入此页面时收到所有需要的查询字符串,我只想自动运行它。

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以在组件函数主体中设置状态,并在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>
  );
}