为什么我的子组件没有从父组件获得状态更新?
Why my child component did not get state update from parent component?
上下文
我正在尝试使用 google-map-react
来展示当地的面包店。
但是,我的子组件 StoresGoogleMap
中的行 console.log(props);
将 storeLocations
和 stores
打印为 []
。如果我在我的 StoresGoogleMap
组件中使用 below,它正在工作:
{props.storeLocations.map((storeLocation) => (
<Marker
key={storeLocation.unique_store_name}
lat={storeLocation.store_location_latitude}
lng={storeLocation.store_location_longitude}
store={storeLocation}
/>
))}
所以我认为这里的问题是子组件 StoresGoogleMap
在父组件 SearchStoresPage
中以初始值呈现,即 []
。但是当父组件的状态改变时不更新。
有什么解决方法的建议吗?
详情
我有一个这样定义的父组件:
const SearchStoresPage = () => {
const [state, setState] = React.useState<StateProperties>(
{stores:[], storeLocations: []}
);
React.useEffect(
() => {
searchStores()
.then(
response => {
const locations : GoogleMapStoreLocation[] = response.map(
(obj:TypeStore) => {
return (
{
store_id: obj['store_id'],
store_name: obj['store_name'],
unique_store_name: obj['unique_store_name'],
store_description: obj['store_description'],
store_website: obj['store_website'],
store_cell_number: obj['store_cell_number'],
store_email: obj['store_email'],
store_location: obj['store_location'],
store_location_latitude: obj['store_location_latitude'],
store_location_longitude: obj['store_location_longitude'],
show: false
}
)
}
);
setState({stores: response, storeLocations: locations});
}
)
.catch(error => console.log(error));
},
[]
);
return (
<div className="flex flex-row">
<StoreList storeList = {state.stores}/>
<StoresGoogleMap storeLocations = {state.storeLocations} stores = {state.stores} defaultCenter={[40.7831, -73.9712]}/>
</div>
);
};
我有一个子组件 StoresGoogleMap
定义如下:
const StoresGoogleMap = (props: StoresGoogleMapProps) => {
const [storeLocations, setStoreLocations] = React.useState<GoogleMapStoreLocation[]>(props.storeLocations);
React.useEffect(
() => {
console.log(props);
setStoreLocations(props.storeLocations);
},
[]
);
const onMarkerClick = (unique_store_name: string) => {
...
};
return (
<div id="map" style={{ height: '100vh', width: '100%' }}>
<GoogleMap
defaultZoom={12}
defaultCenter={props.defaultCenter}
bootstrapURLKeys={{ key: process.env.REACT_APP_GOOGLE_MAP_API_KEY }}
onChildClick={onMarkerClick}
>
{storeLocations.map((storeLocation) => (
<Marker
key={storeLocation.unique_store_name}
lat={storeLocation.store_location_latitude}
lng={storeLocation.store_location_longitude}
store={storeLocation}
/>
))}
</GoogleMap>
</div>
);
};
So I think here the problem is that the child component StoresGoogleMap is rendered with initial value in parent component SearchStoresPage, which is []. But not updated when parent component's state changed. Any suggestion how to fix this?
解决此问题的一种方法是在父组件中的数据更改时在子组件中触发 useEffect
--> 通过在 StoresGoogleMap
useEffect() 中添加 props.storeLocations
作为依赖项
因为您在 child 组件的 useEffect 中传递了空数组 []
,所以它 运行 只有第一次呈现。
现在假设您的数据已获取,因此 child 组件将是 re-rendered 但您的 useEffect 不会再次 运行 因为您在依赖项中传递了一个空数组。
因此您可以安全地使用 props.storeLocations.map
或从 useEffect
中删除 []
但这会导致在每个渲染上出现 useEffect
运行,因此您可以将 props.storeLocations
添加到您的 child useEffect
依赖项中。
但我真的看不出使用 child 状态与道具相同的意义,如果你只是为了渲染目的使用它
上下文
我正在尝试使用 google-map-react
来展示当地的面包店。
但是,我的子组件 StoresGoogleMap
中的行 console.log(props);
将 storeLocations
和 stores
打印为 []
。如果我在我的 StoresGoogleMap
组件中使用 below,它正在工作:
{props.storeLocations.map((storeLocation) => (
<Marker
key={storeLocation.unique_store_name}
lat={storeLocation.store_location_latitude}
lng={storeLocation.store_location_longitude}
store={storeLocation}
/>
))}
所以我认为这里的问题是子组件 StoresGoogleMap
在父组件 SearchStoresPage
中以初始值呈现,即 []
。但是当父组件的状态改变时不更新。
有什么解决方法的建议吗?
详情
我有一个这样定义的父组件:
const SearchStoresPage = () => {
const [state, setState] = React.useState<StateProperties>(
{stores:[], storeLocations: []}
);
React.useEffect(
() => {
searchStores()
.then(
response => {
const locations : GoogleMapStoreLocation[] = response.map(
(obj:TypeStore) => {
return (
{
store_id: obj['store_id'],
store_name: obj['store_name'],
unique_store_name: obj['unique_store_name'],
store_description: obj['store_description'],
store_website: obj['store_website'],
store_cell_number: obj['store_cell_number'],
store_email: obj['store_email'],
store_location: obj['store_location'],
store_location_latitude: obj['store_location_latitude'],
store_location_longitude: obj['store_location_longitude'],
show: false
}
)
}
);
setState({stores: response, storeLocations: locations});
}
)
.catch(error => console.log(error));
},
[]
);
return (
<div className="flex flex-row">
<StoreList storeList = {state.stores}/>
<StoresGoogleMap storeLocations = {state.storeLocations} stores = {state.stores} defaultCenter={[40.7831, -73.9712]}/>
</div>
);
};
我有一个子组件 StoresGoogleMap
定义如下:
const StoresGoogleMap = (props: StoresGoogleMapProps) => {
const [storeLocations, setStoreLocations] = React.useState<GoogleMapStoreLocation[]>(props.storeLocations);
React.useEffect(
() => {
console.log(props);
setStoreLocations(props.storeLocations);
},
[]
);
const onMarkerClick = (unique_store_name: string) => {
...
};
return (
<div id="map" style={{ height: '100vh', width: '100%' }}>
<GoogleMap
defaultZoom={12}
defaultCenter={props.defaultCenter}
bootstrapURLKeys={{ key: process.env.REACT_APP_GOOGLE_MAP_API_KEY }}
onChildClick={onMarkerClick}
>
{storeLocations.map((storeLocation) => (
<Marker
key={storeLocation.unique_store_name}
lat={storeLocation.store_location_latitude}
lng={storeLocation.store_location_longitude}
store={storeLocation}
/>
))}
</GoogleMap>
</div>
);
};
So I think here the problem is that the child component StoresGoogleMap is rendered with initial value in parent component SearchStoresPage, which is []. But not updated when parent component's state changed. Any suggestion how to fix this?
解决此问题的一种方法是在父组件中的数据更改时在子组件中触发 useEffect
--> 通过在 StoresGoogleMap
useEffect() 中添加 props.storeLocations
作为依赖项
因为您在 child 组件的 useEffect 中传递了空数组 []
,所以它 运行 只有第一次呈现。
现在假设您的数据已获取,因此 child 组件将是 re-rendered 但您的 useEffect 不会再次 运行 因为您在依赖项中传递了一个空数组。
因此您可以安全地使用 props.storeLocations.map
或从 useEffect
中删除 []
但这会导致在每个渲染上出现 useEffect
运行,因此您可以将 props.storeLocations
添加到您的 child useEffect
依赖项中。
但我真的看不出使用 child 状态与道具相同的意义,如果你只是为了渲染目的使用它