【问题标题】:React - Invariant Violation: Maximum update depth exceededReact - 不变违规:超过最大更新深度
【发布时间】:2020-08-11 23:05:27
【问题描述】:

我有从另一个类设置我的状态的功能,但是我收到了以下错误

已超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。

这是我的代码

  constructor(props) {
    super(props)
    this.state = { loading: true, showAction: false }
    setTimeout(() => {
      StatusBar.setBackgroundColor(primary)
    }, 100)
  }

  async componentWillMount() {
    await Font.loadAsync({
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      Ionicons: require("@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf"),
    });
    this.setState({ loading: false });
  }

  setShowAction = (isShowAction) => {
    console.log(isShowAction)
    this.setState({
      showAction: isShowAction
    })
  }

...

<ChatListScreen onAction={(isShowAction) => this.setShowAction(isShowAction)}/>

...

const ChatListScreen = ({ onAction }) => {

    return (
        <ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
    )
}

...

const ChatList = ({ onAction }) => {
    const [selectMode, setSelectMode] = useState(false)
    const chatListDummy = []
    const [selectedItem, setSelectedItem] = useState([])
    {selectMode ? onAction(true) : onAction(false)}
    return (
        <FlatList
                data= {chatListDummy}
                keyExtractor= {chat => chat.id}
                renderItem= {({item}) => {
                }}/>
    )
}

export default ChatList

谁能帮忙?

【问题讨论】:

  • 你能告诉我们ChatListScreen代码吗?
  • 您可能需要在代码中使用箭头函数。当您没有正确绑定您的方法时,反应开始连续调用它们......这会导致最大更新深度超出错误
  • {selectMode ? onAction(true) : onAction(false)} 嗨,你在哪里使用这个?在渲染或函数或生命周期中?
  • 如何将{selectMode ? onAction(true) : onAction(false)} 放入useEffect

标签: reactjs react-native react-state-management


【解决方案1】:

查看我的解决方案

const ChatListScreen = ({ onAction }) => {

   return (
       <ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
   )
}
const ChatList = ({ onAction }) => {
   const [selectMode, setSelectMode] = useState(false)
   const [selectedItem, setSelectedItem] = useState([])
   //i dont know where are you using this actally you most use this in a lifesycle or a function
   // {selectMode ? onAction(true) : onAction(false)}
function onClick(){
   selectMode ? onAction(true) : onAction(false)

}
//or a lifecycle
useEffect(()=>{
   selectMode ? onAction(true) : onAction(false)

},[])
return (<div onClick ={onClick} >{"your content"}</div>)

【讨论】:

    【解决方案2】:

    尽量避免将匿名函数作为 props 传递给 React 组件。这是因为 React 总是会重新渲染你的组件,因为它将无法将其状态与前一个进行比较,这也是一个匿名函数。

    话虽如此,在某些情况下传递匿名函数是不可避免的。在这种情况下,永远不要在匿名函数中更新你的状态。这是您的场景中的主要问题,这是发生了什么:

    1. 您将匿名函数作为道具传递给您的组件。
    2. 当组件接收到这个函数时,它无法与之前的状态进行比较,因此重新渲染你的组件。
    3. 在您的匿名函数中,您正在更新您的状态。更新你的状态会迫使 React 再次重新渲染组件。
        this.setState({
          showAction: isShowAction
        }) //this portion is mainly responsible for the error
    
    1. 因此这个循环一直持续到一个阈值,直到 React 抛出一个错误Maximum update depth exceeded.

    【讨论】:

    • 好吧,那应该怎么样?因为在这种情况下,我想从其子组件设置状态
    • 使用任何状态管理工具以集中方式管理您的应用状态,然后将您的状态映射到道具并将它们用作组件中的道具。
    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 2020-06-14
    • 2019-04-03
    相关资源
    最近更新 更多