React Native无法使用强制更新或设置状态呈现页面

时间:2018-08-12 04:40:23

标签: react-native asyncstorage rerender

class Wait extends Component{

constructor(props) {
  super(props);
  this.state = { fetchingData: true, data: [], check: ''}
  this.forceUpdateHandler.bind(this);
  }

getData = async() => {
  try {
    data = await AsyncStorage.getItem('restaurants');
    if (data != null) {
      this.setState({fetchingData: false , data: JSON.parse(data)})
    }
  } catch(error){
     console.log(error)
  }
}

forceUpdateHandler(){
    this.forceUpdate();
};

componentDidMount(){
  this.getData();
}

renderRestaurant(){
  return this.state.data.map((item) => {
    return (
    <View style ={{marginTop: 20, backgroundColor: 'red', marginTop: 20 }}>
      <Text> {item.name} </Text>
      <Text> {item.time} </Text>
      <Text> {item.wait} </Text>
      <Text> {item.people} </Text>
      <Button title = 'cancel' onPress = { async () => {
        let data = await AsyncStorage.getItem('restaurants');
        let temp = JSON.parse(data)
        let i = -1
        temp.map((value, index) => {
          if (value.name == item.name){
            i = index;
          }
        })
        if (i > -1){
          temp.splice(i, 1)
          await AsyncStorage.setItem('restaurants', JSON.stringify(temp))
        }
        this.forceUpdateHandler()         // First way
        this.forceUpdate()                // Second way
        this.setState({check: 'checked'})   // Third way
      }
      }
      />
    </View>
  )
})
}

render(){
  const { navigate } = this.props.navigation;
  const { navigation } = this.props;

  return (
    <View style={{width:200, height:200, justifyContent:'center', alignItems:'center', }}>
          {this.state.fetchingData ? null : this.renderRestaurant()}
    </View>
  )
}
}

单击按钮后,每次尝试重新渲染页面。单击按钮后,它将访问AsyncStorage并删除阵列中的相应元素,然后使用新阵列更新AsyncStorage并重新呈现页面。

我尝试了以下方法:

1) call forUpdate directly after the update of the AsyncStorage
2) define the forceUpdateHandler function and bind it with this
3) call this.setState after the update of the AsyncStorage

但是以上选项均未重新呈现该页面。有人可以帮助修复它吗?一个例子会很棒!提前致谢。

2 个答案:

答案 0 :(得分:0)

答案很简单。它不会重新渲染,因为它没有要重新渲染的内容。它调用渲染,检查渲染中的每个组件是否改变了用于渲染它的数据,并在需要时渲染它们。如果您查看代码,则会看到按下按钮后,会将新数据保存在异步存储中。但是,您的渲染使用this.state.data来渲染项目。问题是您永远不会使用新数据更新组件的状态。

当然,您进行了this.setState({check: 'checked'}),但渲染器中没有任何东西正在使用它。因此,更新UI毫无意义。

一种简单的解决方法是在按钮this.getData()的末尾调用onPress。这样,您将更新将更新您的UI的数据状态。

答案 1 :(得分:0)

  1. 获取餐厅的更新列表{删除所选餐厅}
  2. 将更新后的列表存储到Asyncstorage。
  3. 从asyncStorage获取更新的列表并设置状态。

 storeData = async (restaurants) => {
    try {
     await AsyncStorage.setItem('restaurants', JSON.stringify(restaurants))
    } catch (error) {
      console.log("Error", error);
    }
  }


renderRestaurant(){
      return this.state.data.map((item, index, restaurants) => {
        return (
          <View key={index}>
            <Text> {item.name} </Text>
            <Text> {item.time} </Text>
            <Button 
              title = 'cancel' 
              onPress = {() => {
                let restaurantListWithoutCurrentRestaurant = restaurants.filter((restaurant)=> restaurant.name !== item.name);
                this.storeData(restaurantListWithoutCurrentRestaurant);
                this.getData();       
            }}/>
          </View>
        )
      })
    }

我认为这可以解决您的问题。