【问题标题】:Setting state of a 'Loading' boolean in react doesn't update在反应中设置“加载”布尔值的状态不会更新
【发布时间】:2021-03-15 08:50:46
【问题描述】:

我有一个页面,允许用户提交从中抓取数据的 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>
</>

然后我在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;

【问题讨论】:

  • 你能告诉我你如何访问上下文吗?没有关于那个的代码
  • 您能否添加一条评论,说明“它没有更新”的位置以及您如何使用它来显示您的“加载”消息
  • 我正在使用 console.log 来检查 loadingState.loading 的值。这在控制台输出中总是出现错误。我现在只是添加显示访问上下文的代码

标签: reactjs setstate use-state


【解决方案1】:

不要使用对象作为布尔值,只是

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

btw 看起来像是一个闭包问题。你看到 loadingState 总是假的导致关闭。 看看这个Be Aware of Stale Closures when Using React Hooks

一种解决方法是使用 refs

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

【讨论】:

  • 你如何获得 loadingState?是单独使用loadingState 还是需要使用loadingState.value 或类似名称。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多