当我在父组件中通过 useState 设置状态时,我传递给的子组件中的道具是未定义的
When I set state via useState in parent component, my props in the child I'm passing down to are undefined
我有一个父组件列表,它有一个种子文件中的对象数组。我只想在页面加载时加载 14 个对象中的前 9 个。
const Listings = () => {
const [ listingsData, setListings] = useState(listings);
const [ homesDisplayed , setDisplayNumber ] = useState(listingsData.slice(0, 9));
const homes = homesDisplayed.map((home, index) => (
<div className="col xl4" key={index}>
<HomeListingCard
name={home.homeName}
imageUrl={home.imageURL}
beds={home.beds}
baths={home.baths}
isMultiSection={home.isMultiSection}
sqft={home.sqft}
startingPrice={home.startingPrice}
/>
</div>
));
return (
<div>
<div className="row">
<div className="listings-subheader">
<h3 className="left available-homes">{`${listingsData.length} `}homes available</h3>
<div className="right">
<SortBy />
</div>
</div>
</div>
<div className="row">
{homes}
</div>
<div className="row">
<LoadListings listings={listingsData} homesDisplayed={homes} setDisplayNumber={setDisplayNumber} />
</div>
</div>
)
}
export default Listings;
我使用 const [ homesDisplayed , setDisplayNumber ] = useState(listingsData.slice(0, 9));
将 9 个对象的数组设置为 state。
这很好用。
然后我尝试将我的状态作为道具传递给子组件,如下所示:
<LoadListings listings={listingsData} homesDisplayed={homes} setDisplayNumber={setDisplayNumber} />
当页面最初加载时,这些道具有数据。但是当我在 <LoadListings />
子组件中点击一个按钮到 console.log(props) 时,我的数据都是未定义的。
<LoadListings />
看起来像:
const LoadListings = (props) => {
const updateListings = (props) => {
console.log(props.homes);
// props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
return (
<button onClick={updateListings}>Load More</button>
)
}
我的目标是单击按钮并updateLIstings
从原来的 14 数组中再拼接 3 个,然后像这样将它们添加到 homeDisplayed 数组中
const updateListings = (props) => {
props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
但是props.homesDisplayed——以及所有的道具——都是未定义的。
谢谢。
发生这种情况是因为您没有实际上将您的道具传递给updateListings
函数。
如果仔细查看函数声明,您会注意到您已将 props
定义为参数。然后,在 onClick
属性上,您实际上并没有将任何东西 传递给 函数。
考虑 updateListings
函数的作用域...您实际上不需要传递任何东西,因为它已经可以从父作用域访问 props
。不幸的是,通过第二次将 props
定义为函数参数,您正在隐藏更高范围的 props
(有效地告诉函数忽略它)。
如果您更新 updateListings
以省略 props
参数,它 应该 工作(除非您的代码中存在任何其他问题)。
const updateListings = (props) => {
console.log(props.homes);
props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
旁注:您可能只想存储要显示的项目数,而不是将切片数据存储在状态中。这样,您就可以通过在渲染本身中执行切片来简化一切,而不是对状态中的数据进行推理。例如:
const [ listingsData, setListings] = useState(listings);
// Store number to display
const [ homesDisplayed , setDisplayNumber ] = useState(9);
// Slice before map, which'll update every time you increment `homesDisplayed
const homes = homesDisplayed.slice(0, homesDisplayed).map((home, index) => (
<div className="col xl4" key={index}>
<HomeListingCard
name={home.homeName}
imageUrl={home.imageURL}
beds={home.beds}
baths={home.baths}
isMultiSection={home.isMultiSection}
sqft={home.sqft}
startingPrice={home.startingPrice}
/>
</div>
));
另一个旁注:通常你会想要命名你的 [state, setState]
val/updater 始终遵循 varName, setVarName
的约定。这样,当您稍后尝试调和什么控制什么时,reader(和您!)就不会那么困惑了。
所以我建议将 [homesDisplayed, setDisplayNumber]
更改为 [displayNumber, setDisplayNumber]
。
我有一个父组件列表,它有一个种子文件中的对象数组。我只想在页面加载时加载 14 个对象中的前 9 个。
const Listings = () => {
const [ listingsData, setListings] = useState(listings);
const [ homesDisplayed , setDisplayNumber ] = useState(listingsData.slice(0, 9));
const homes = homesDisplayed.map((home, index) => (
<div className="col xl4" key={index}>
<HomeListingCard
name={home.homeName}
imageUrl={home.imageURL}
beds={home.beds}
baths={home.baths}
isMultiSection={home.isMultiSection}
sqft={home.sqft}
startingPrice={home.startingPrice}
/>
</div>
));
return (
<div>
<div className="row">
<div className="listings-subheader">
<h3 className="left available-homes">{`${listingsData.length} `}homes available</h3>
<div className="right">
<SortBy />
</div>
</div>
</div>
<div className="row">
{homes}
</div>
<div className="row">
<LoadListings listings={listingsData} homesDisplayed={homes} setDisplayNumber={setDisplayNumber} />
</div>
</div>
)
}
export default Listings;
我使用 const [ homesDisplayed , setDisplayNumber ] = useState(listingsData.slice(0, 9));
将 9 个对象的数组设置为 state。
这很好用。
然后我尝试将我的状态作为道具传递给子组件,如下所示:
<LoadListings listings={listingsData} homesDisplayed={homes} setDisplayNumber={setDisplayNumber} />
当页面最初加载时,这些道具有数据。但是当我在 <LoadListings />
子组件中点击一个按钮到 console.log(props) 时,我的数据都是未定义的。
<LoadListings />
看起来像:
const LoadListings = (props) => {
const updateListings = (props) => {
console.log(props.homes);
// props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
return (
<button onClick={updateListings}>Load More</button>
)
}
我的目标是单击按钮并updateLIstings
从原来的 14 数组中再拼接 3 个,然后像这样将它们添加到 homeDisplayed 数组中
const updateListings = (props) => {
props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
但是props.homesDisplayed——以及所有的道具——都是未定义的。
谢谢。
发生这种情况是因为您没有实际上将您的道具传递给updateListings
函数。
如果仔细查看函数声明,您会注意到您已将 props
定义为参数。然后,在 onClick
属性上,您实际上并没有将任何东西 传递给 函数。
考虑 updateListings
函数的作用域...您实际上不需要传递任何东西,因为它已经可以从父作用域访问 props
。不幸的是,通过第二次将 props
定义为函数参数,您正在隐藏更高范围的 props
(有效地告诉函数忽略它)。
如果您更新 updateListings
以省略 props
参数,它 应该 工作(除非您的代码中存在任何其他问题)。
const updateListings = (props) => {
console.log(props.homes);
props.setDisplayNumber(...props.homesDisplayed, props.listings.slice(9, 12));
}
旁注:您可能只想存储要显示的项目数,而不是将切片数据存储在状态中。这样,您就可以通过在渲染本身中执行切片来简化一切,而不是对状态中的数据进行推理。例如:
const [ listingsData, setListings] = useState(listings);
// Store number to display
const [ homesDisplayed , setDisplayNumber ] = useState(9);
// Slice before map, which'll update every time you increment `homesDisplayed
const homes = homesDisplayed.slice(0, homesDisplayed).map((home, index) => (
<div className="col xl4" key={index}>
<HomeListingCard
name={home.homeName}
imageUrl={home.imageURL}
beds={home.beds}
baths={home.baths}
isMultiSection={home.isMultiSection}
sqft={home.sqft}
startingPrice={home.startingPrice}
/>
</div>
));
另一个旁注:通常你会想要命名你的 [state, setState]
val/updater 始终遵循 varName, setVarName
的约定。这样,当您稍后尝试调和什么控制什么时,reader(和您!)就不会那么困惑了。
所以我建议将 [homesDisplayed, setDisplayNumber]
更改为 [displayNumber, setDisplayNumber]
。