简体   繁体   English

使用带有功能组件的道具更新组件的 state

[英]Updating component's state using props with functional components

I am trying to update the state of my component using props that I get from the parent component, but I get the following error message:我正在尝试使用从父组件获得的道具更新我的组件的 state,但我收到以下错误消息:

Too many re-renders.太多的重新渲染。 React limits the number of renders to prevent an infinite loop. React 限制了渲染的数量以防止无限循环。

I want the local state to update if the prop changes.如果道具发生变化,我希望本地 state 更新。 The similar posts ( Updating component's state using props , Updating state with props on React child component , Updating component's state using props ) did not fixed it for me.类似的帖子( 使用道具更新组件的 state ,使用React 子组件上的道具更新 state , 使用道具更新组件的 Z9ED39E2EA931586B6A985A6942EF573E没有修复它)。

import React, {useState} from "react"


const HomeWorld = (props) => {
    const [planetData, setPlanetData] = useState([]);
    if(props.Selected === true){
        setPlanetData(props.Planet)
        console.log(planetData)
    }


    return(
        <h1>hi i am your starship, type: {planetData}</h1>
    )
}

export default HomeWorld

You need to use the useEffect hook to run it only once.您只需要使用useEffect挂钩来运行它一次。

import { useEffect }  from 'react'

... 

const HomeWorld = (props) => {
    const [planetData, setPlanetData] = useState([]);

    useEffect(() => {
        if(props.Selected === true){
            setPlanetData(props.Planet)
            console.log(planetData)
        }
    }, [props.Selected, props.Planet, setPlanetData]) // This will only run when one of those variables change

    return(
        <h1>hi i am your starship, type: {planetData}</h1>
    )
}

Please notice that if props.Selected or props.Planet change, it will re run the effect.请注意,如果props.Selectedprops.Planet发生变化,它会重新运行效果。

Why Do I Get This Error?为什么会出现此错误?

Too many re-renders.太多的重新渲染。 React limits the number of renders to prevent an infinite loop. React 限制了渲染的数量以防止无限循环。

What is happening here is that when your component renders, it runs everything in the function, calling setPlanetData wich will rerender the component, calling everything inside the function again ( setPlanetData again) and making a infinite loop.这里发生的是,当您的组件渲染时,它运行 function 中的所有内容,调用setPlanetData将重新渲染组件,再次调用 function 中的所有内容(再次setPlanetData )并进行无限循环。

You're generally better off not updating your state with props.你通常最好不要用道具更新你的 state 。 It generally makes the component hard to reason about and can often lead to unexpected states and stale data.它通常使组件难以推理,并且通常会导致意外状态和陈旧数据。 Instead, I would consider something like:相反,我会考虑类似的事情:

const HomeWorld = (props) => {
    const planetData = props.Selected
        ? props.Planet
        //... what to display when its not selected, perhaps:
        : props.PreviousPlanet

    return(
        <h1>hi i am your starship, type: {planetData}</h1>
    )
}

This might require a bit more logic in the parent component, to control what displays when the Selected prop is false, but it's a lot more idiomatic React.这可能需要在父组件中添加更多逻辑,以控制 Selected 属性为 false 时显示的内容,但它更符合 React 的习惯。

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

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