简体   繁体   English

state 更改后反应组件未重新渲染

[英]react component not re-rendering after state change

It is rendering incorrectly when the page state changes I click on the category link and it checks if the link exists in category and then should set page state to category and likewise if I click on the recipe link it should set page state to recipe .page state 更改时呈现不正确我单击类别链接并检查该链接是否存在于类别中,然后应将page state 设置为category ,同样,如果我单击配方链接,它应该将page Z9ED39E2EA931586B3EZEF 设置为recipe

The value of isRecipe and isCategory are correct but it only sets the page state correctly after refreshing the page. isRecipeisCategory的值是正确的,但它只在刷新页面后正确设置page state。

It should watch the page state and if this changes then it should re-render the component它应该观看页面 state,如果它发生变化,那么它应该重新渲染组件

How can I re-render the component if the page state changes?如果页面 state 发生更改,我如何重新渲染组件?

const categories = [
 {name: 'first', slug: 'first'}, 
 {name: 'second', slug: 'second'},
]

const recipes = [
 {name: 'firstRecipe', slug: 'firstRecipe'},
 {name: 'secondRecipe', slug: 'secondRecipe'},
]

const Categories = ({ categories, recipe, recipes }) => {
  const router = useRouter()
  const { slug } = router.query

  const isRecipe = !!recipes.find(recipe => recipe.slug === slug)
  const isCategory = !!categories.find(cat => cat.slug === slug)

  const [page, setPage] = useState('')

  useEffect(() => {
    !!isCategory && setPage('category')
    !!isRecipe && setPage('recipe')
    }, [page])
  
  return (
    <>
      <a href="/first"> category </a>
      <a href="/firstRecipe"> recipe </a>
      {page === 'category' && <Category /> }
      {page === 'recipe' && <Recipes /> }
    </>
  )
}

export default Categories

Try this, with the additions to the dependencies:试试这个,添加依赖项:

const categories = [
 {name: 'first', slug: 'first'}, 
 {name: 'second', slug: 'second'},
]

const recipes = [
 {name: 'firstRecipe', slug: 'firstRecipe'},
 {name: 'secondRecipe', slug: 'secondRecipe'},
]

const Categories = ({ categories, recipe, recipes }) => {
  const router = useRouter()
  const { slug } = router.query

  const isRecipe = !!recipes.find(recipe => recipe.slug === slug)
  const isCategory = !!categories.find(cat => cat.slug === slug)

  const [page, setPage] = useState('')

  useEffect(() => {
    !!isCategory && setPage('category')
    !!isRecipe && setPage('recipe')
    }, [page, isRecipe, isCategory  ])
  
  return (
    <>
      <a href="/first"> category </a>
      <a href="/firstRecipe"> recipe </a>
      {page === 'category' && <Category /> }
      {page === 'recipe' && <Recipes /> }
    </>
  )
}

The dependencies of the useEffect hook are actually isRecipe and isCategory so instead of [page] , the effect should depend on [isRecipe, isCategory] . useEffect挂钩的依赖项实际上是isRecipeisCategory ,所以效果应该依赖于[isRecipe, isCategory]而不是[page] ] 。

Alternately, as the helpers ( isCategory and isRecipe ) are derived from the slug , they could be moved into the hook and then only [slug] would be required to set the proper hook dependencies.或者,由于助手( isCategoryisRecipe )是从slug派生的,它们可以被移动到钩子中,然后只需要[slug]来设置正确的钩子依赖项。

Note: The setPage is not required to be given to the hook dependency list as it is guaranteed to be stable by React - omitting it is safe.注意: setPage不需要提供给钩子依赖列表,因为 React 保证它是稳定的 - 省略它是安全的。

Ideally, the state could be avoided entirely by a simple computation like this:理想情况下,可以通过如下简单计算完全避免 state:

page = null

if (isRecipe) {
  page = <Recipe />
} else if (isCategory) {
  page = <Category/>
}

...

<>
  ...
  {page}
<\>

There are actually three possible cases: recipe page, category page, and others that do not match the first two, which by rendering null will most likely result in what was anticipated by the code above.实际上存在三种可能的情况:配方页面、类别页面以及与前两种不匹配的其他情况,通过呈现null很可能会导致上述代码所预期的结果。

Having less state, hooks, and mutations, results in less moving parts, thus most likely less bugs更少的 state、钩子和突变导致更少的移动部件,因此很可能更少的错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM