【发布时间】:2020-01-06 18:21:46
【问题描述】:
这是我的代码:https://codesandbox.io/s/gatsby-starter-default-og782
逻辑很简单:我用 Gatsby.js 和 React 渲染了一个Gallery 组件
<StaticQuery
query={graphql`
{
allFile(
filter: {
extension: { regex: "/(jpg)|(jpeg)|(png)/" }
sourceInstanceName: { eq: "images" }
}
) {
edges {
node {
childImageSharp {
fluid(maxWidth: 800, quality: 95) {
aspectRatio
src
srcSet
originalName
srcWebp
srcSetWebp
sizes
}
}
}
}
}
}
`}
render={data => (
<Layout>
<Gallery minWidth={200} data={data.allFile.edges} />
</Layout>
)}
/>
这将为Gallery 提供要显示的图像文件。
在Gallery里面,我有这些状态
const [allPics, setAllPics] = useState([]) <-- storing all the image files
const [currentImgs, setCurrentImgs] = useState([]) <-- storing the images of the current tab
const [tabs, setTabs] = useState([])
useEffect 在组件挂载时只运行一次
useEffect(() => {
const allPics = data.map((img, i) => {
img.node.childImageSharp.index = i
return img.node.childImageSharp
})
setAllPics(allPics)
setTabs(getAllTabs(allPics))
// default tab when the page first loads
setCurrentImgs(
allPics.filter(({ fluid }) => fluid.originalName.includes(tabs[0]))
)
}, [data])
然后我用这个渲染
<>
<ProjectsContainer>
{tabs.map(tab => (
<Project
key={tab}
onClick={() => {
setCurrentImgs(
allPics.filter(({ fluid }) => fluid.originalName.includes(tab))
)
}}
>
{tab}
</Project>
))}
</ProjectsContainer>
<Mansory gap={"0em"} minWidth={minWidth}>
{currentImgs.map((img, i) => {
return (
<PicContainer
index={img.index}
selected={isSelected}
key={img.index}
>
<Enlarger
src={img.fluid.srcSet.split(" ")[0]}
enlargedSrc={img.fluid.src}
index={img.index}
setIsSelected={setIsSelected}
onLoad={() => {
setTimeout(() => {
refs[img.index].current.toggleOpacity(1)
}, 300)
}}
ref={refs[img.index]}
realIndex={i}
/>
</PicContainer>
)
})}
</Mansory>
</>
问题是,状态currentImgs 似乎仍然是一个空数组,这是useEffect 运行后的默认状态,所以当我们第一次加载页面时,没有当前图像可以显示。您必须手动单击这些选项卡中的任何一个才能再次触发setCurrentImgs 以显示当前图像。
所以问题似乎很明显,就是为什么useEffect中只有currentImgs状态设置不正确,而allPics和tabs等其他状态设置正确?
【问题讨论】:
标签: javascript reactjs frontend gatsby