React 上下文不在组件之间共享
React context not shared between components
我在两个组件之间使用了一个反应上下文,但是当我在子 filtersBar 组件中设置这个上下文的值时,它不会在第二个子地图组件中更新或使用效果。
上下文提供者
const SearchContext = createContext();
const SearchContextProvider = ({children}) => {
const [contextValue, setContextValue] = useState(null);
return (
<SearchContext.Provider value={[contextValue, setContextValue]}>
{children}
</SearchContext.Provider>
);
index.js
<SearchContextProvider>
<FiltersBar/>
<Map/>
</SearchContextProvider>
Filtersbar.js
const FiltersBar = () => {
const [searchContext,setSearchContext] = useContext(SearchContext);
const [searchLocationResult, setsearchLocationResult] = useState(null);
const [inputSearchLocation, setinputSearchLocation] = useState("");
useEffect(() => {
// stuff
searchContext.autocompleteLocation = [46.6, 8.5]
setSearchContext(searchContext)
}, [searchLocationResult, inputSearchLocation]);
Map.js
const Map = () => {
const [searchContext, setSearchContext] = useContext(SearchContext);
useEffect(() => {
console.log("use effect map"+JSON.stringify(searchContext))
}, [searchContext]);
我从来没有看到这个使用效果图控制台日志消息。我错过了什么?
因为这个
useEffect(() => {
/// stuff
setSearchContext(searchContext) // ----> here
}, [searchLocationResult, inputSearchLocation]);
searchContext
永远不会改变。它始终为空,您始终将 null
设置为 setSearchContext
函数。
也许你只会在重新加载或组件初始化时得到第一个 console.log 就像 use effect mapnull
如果您显示的代码是您真实代码的准确表示,那么问题是您正在改变状态,而不是创建新状态。当您设置状态时,React 会在之前的状态和之后的状态之间执行 ===
。它看到它们是同一个对象,所以它认为什么都没有改变,它什么也不做。
所以不是这个:
searchContext.autocompleteLocation = [46.6, 8.5]
setSearchContext(searchContext)
这样做:
const newState = {
...searchContext,
autocompleteLocation: [46.6, 8.5]
}
setSearchContext(newState);
React hook 与 Class 组件中的 React state 有点不同。 React hook 仅当它是新对象时才考虑状态变化,你应该在更新状态时创建新对象。
您可以更新 FiltersBar 的 useEffect 如下:
Filtersbar.js
const FiltersBar = () => {
...
useEffect(() => {
// stuff
setSearchContext({...searchContext, autocompleteLocation: [46.6, 8.5]})
}, [searchLocationResult, inputSearchLocation]);
我在两个组件之间使用了一个反应上下文,但是当我在子 filtersBar 组件中设置这个上下文的值时,它不会在第二个子地图组件中更新或使用效果。
上下文提供者
const SearchContext = createContext();
const SearchContextProvider = ({children}) => {
const [contextValue, setContextValue] = useState(null);
return (
<SearchContext.Provider value={[contextValue, setContextValue]}>
{children}
</SearchContext.Provider>
);
index.js
<SearchContextProvider>
<FiltersBar/>
<Map/>
</SearchContextProvider>
Filtersbar.js
const FiltersBar = () => {
const [searchContext,setSearchContext] = useContext(SearchContext);
const [searchLocationResult, setsearchLocationResult] = useState(null);
const [inputSearchLocation, setinputSearchLocation] = useState("");
useEffect(() => {
// stuff
searchContext.autocompleteLocation = [46.6, 8.5]
setSearchContext(searchContext)
}, [searchLocationResult, inputSearchLocation]);
Map.js
const Map = () => {
const [searchContext, setSearchContext] = useContext(SearchContext);
useEffect(() => {
console.log("use effect map"+JSON.stringify(searchContext))
}, [searchContext]);
我从来没有看到这个使用效果图控制台日志消息。我错过了什么?
因为这个
useEffect(() => {
/// stuff
setSearchContext(searchContext) // ----> here
}, [searchLocationResult, inputSearchLocation]);
searchContext
永远不会改变。它始终为空,您始终将 null
设置为 setSearchContext
函数。
也许你只会在重新加载或组件初始化时得到第一个 console.log 就像 use effect mapnull
如果您显示的代码是您真实代码的准确表示,那么问题是您正在改变状态,而不是创建新状态。当您设置状态时,React 会在之前的状态和之后的状态之间执行 ===
。它看到它们是同一个对象,所以它认为什么都没有改变,它什么也不做。
所以不是这个:
searchContext.autocompleteLocation = [46.6, 8.5]
setSearchContext(searchContext)
这样做:
const newState = {
...searchContext,
autocompleteLocation: [46.6, 8.5]
}
setSearchContext(newState);
React hook 与 Class 组件中的 React state 有点不同。 React hook 仅当它是新对象时才考虑状态变化,你应该在更新状态时创建新对象。
您可以更新 FiltersBar 的 useEffect 如下:
Filtersbar.js
const FiltersBar = () => {
...
useEffect(() => {
// stuff
setSearchContext({...searchContext, autocompleteLocation: [46.6, 8.5]})
}, [searchLocationResult, inputSearchLocation]);