使用带有功能组件的prop更新组件的状态

时间:2019-09-24 13:46:25

标签: javascript reactjs react-hooks

我正在尝试使用从父组件获得的道具来更新组件的状态,但是出现以下错误消息:

  

重新渲染过多。 React限制了渲染次数以防止无限循环。

如果道具更改,我希望更新本地状态。 类似的帖子(Updating component's state using propsUpdating state with props on React child componentUpdating component's state using props)并没有为我解决。

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

2 个答案:

答案 0 :(得分:3)

您只需使用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>
    )
}

请注意,如果更改props.Selectedprops.Planet,它将重新运行效果。

为什么会出现此错误?

  

重新渲染过多。 React限制了渲染次数以防止无限循环。

这里发生的是,当您的组件渲染时,它将运行函数中的所有内容,调用setPlanetData至此将重新渲染组件,再次调用函数中的所有内容(再次调用setPlanetData),并进行无限循环。

答案 1 :(得分:0)

通常最好不要使用道具来更新状态。通常,它使组件难以推理,并经常导致意外状态和陈旧数据。相反,我会考虑类似的东西:

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>
    )
}

这可能需要在父组件中使用更多的逻辑,以控制Selected道具为false时显示的内容,但这是更多惯用的React。