“ prevState”和“ prevProps”在React Native中的行为不正常

时间:2019-03-27 01:54:41

标签: javascript reactjs react-native

在我的React Native项目中,我的状态中有一个数组,如下所示:

constructor(props) {
  super(props)
  this.state = {
    a: [1, 2, 3]
  }
}

我单击一个按钮以更新阵列,如下所示:

<TouchableOpacity
  onPress={() => {this.setState({a: [5, 6]})}
/>

我想用我的componentDidUpdate()方法验证状态更改,如下所示:

componentDidUpdate(prevProps, prevState) {
  console.log("prevState: ", prevState)
  console.log("state: ", this.state)
}

但这总是给

prevState:  (5) [-1, -1, -1, -1, -1]
state:  (5) [-1, -1, -1, -1, -1]

我使用devTools确认了数组确实已更新为[5,6],但是componentDidUpdate()方法仍然只是返回旧值。知道为什么吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

componentDidUpdate()应该始终包裹在一个条件中,以便您需要添加setState()方法。

根据文档:https://reactjs.org/docs/react-component.html#componentdidupdate

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}
  

您可以在componentDidUpdate()中立即调用setState(),但请注意   必须将其包装在上面示例中所示的条件下,或者   您将导致无限循环。这也会造成额外的   重新渲染虽然对用户不可见,但可能会影响   组件性能

还要检查此答案以供参考: Correct modification of state arrays in ReactJS

答案 1 :(得分:2)

我确实实现了您的代码,我的代码正在工作。

这是我的代码:

import React, { Component } from "react";
import { View, Text, Button, SafeAreaView } from "react-native";

import { baseStyles as styles  } from "../styles";

export default class Fetch extends Component{
  constructor(props) {
    super(props)
    this.state = {
      a:[1, 2, 3]
    }
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("prevState: ", prevState)
    console.log("state: ", this.state)
    alert(this.state.a)
  }

  render(){
    return(
    <SafeAreaView>

        <View style={styles.container}>
        <Text>
            Main Dish
        </Text>
        <Button
        title='press'
  onPress={() => {this.setState({a: [5, 6]})}}
/>
        </View>


    </SafeAreaView>

    )
  }
}

答案 2 :(得分:1)

  1. 确保要比较两个数组:
componentDidUpdate(prevProps){
  if(JSON.stringify(prevProps.todos) !== JSON.stringify(this.props.todos){...}
}
  1. 确保在深克隆之后更改传递的道具(父项中的状态):
let newtodos = JSON.parse(JSON.stringify(this.state.todos));
newtodos[0].text = 'changed text';
this.setState({ todos : newtodos });