在反应中设置 '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
我有一个页面允许用户提交 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