在反应中设置 'Loading' 布尔值的状态不会更新

Setting state of a 'Loading' boolean in react doesn't update

我有一个页面允许用户提交 url 从中抓取数据。随后会向用户显示过滤后的数据。

因为抓取需要一些时间我想实现一个加载器。虽然加载程序 class 将(希望)相对简单,但我遇到问题的是 loading 的状态。状态本身永远不会更新。虽然其他状态值如setFilters.

Body.js

const [searchState, setSearchState] = useState({
  searchCriteria: "https://en.wikipedia.org/wiki/2020_Central_Vietnam_floods",
  headers:[],
  references: []
});

const [filterState, setFilters] = useState({
  languageFilter: ""
});

const [loadingState, setLoadingState] = useState({
  loading: false
});

以上都是通过context

传入Search
<>
  <SearchContext.Provider value={{searchState, setSearchState,filterState, setFilters, loadingState, setLoadingState}} >
      <Search />
      <DonateButton />
      <WikiHeaderGroup />
  </SearchContext.Provider>
</>

然后我在 Search 组件中有一个 handleSubmit

Search.js

import React, {useContext} from "react";
import {SearchContext} from "../../contexts/SearchContext"
import "../../App.css"

export function Search (){

  const {searchState, setSearchState, filterState, setFilters, loadingState, setLoadingState} = useContext(SearchContext);

  const handleSubmit = (event) => {
      setFilters({languageFilter:""})
      setLoadingState({loading:true})
      console.log("Loading State : " + loadingState.loading)

      event.preventDefault();
      event.persist();            //persists the event object into the function

      const fetchReferences = async () => {

        fetch('http://127.0.0.1:8080/search/', {
          method: 'POST',
          body: JSON.stringify({
            url: searchState.searchCriteria
            }),
          headers: {"Content-type": "application/json; charset=UTF-8"}

        }).then(response => {
                console.log(response)
                return response.json()

        }).then(json => {
          console.log(json)
          setSearchState({
            headers:json.headers,
            references:json.references
          })
          setLoadingState({loading:false})
          console.log("Loading State : " + loadingState.loading)
    });}

      fetchReferences();
  }

    return (
      <div className="search container">
        <div className="input-group input-group-sm mb-3 center">
          <div className="input-group-prepend">
            <span className="input-group-text" id="inputGroup-sizing-sm">Wikipedia URL:</span>
          </div>

          <form onSubmit={(event) => handleSubmit(event)}>
          <input
            type="text"
            id="searchBox"
            className="form-control center"
            aria-label="Sizing example input"
            aria-describedby="inputGroup-sizing-sm"
            value={searchState.searchCriteria}
            onChange={(event) => setSearchState({searchCriteria:event.target.value, resultId:0})}
            placeholder="Add a url" />
          </form>
        </div>
      </div>
    );

}
export default Search;

不要将对象用于布尔值,只是

const [loadingState, setLoadingState] = useState(false);
....
setLoadingState(true)

顺便说一句,看起来像是一个闭包问题。你看到 loadingState 总是 false 导致关闭。 看看这个 Be Aware of Stale Closures when Using React Hooks

一种解决方法是使用 refs

const loadingStateRef = useRef(loadingState);
//then inside the function u can access 
latestValue.current