0

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

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

正文.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
});

以上都是通过Search上下文传入的

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

然后我有一个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;
4

1 回答 1

0

don't use object for booleans, just

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

btw looks like a closure problem. you see loadingState always false cause the closure. take a look at this Be Aware of Stale Closures when Using React Hooks

A way to solve it is using refs

const loadingStateRef = useRef(loadingState);
//then inside the function u can access 
latestValue.current
于 2020-12-03T10:49:25.350 回答