setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作

时间:2017-10-19 13:29:46

标签: javascript reactjs firebase react-native

  

只能更新已安装或安装的组件。这通常意味着   你在unmounted上调用了setState,replaceState或forceUpdate   零件。这是一个无操作。

     

请检查菜单组件的代码。

我不知道会发生什么。我只是在我的项目中发现这个错误。我不太了解此错误,因为此错误并未向我提供具体信息。现在,我很困惑这个错误让我有点紧张

export default class Menu extends Component {
    constructor(){
        super();
        this.state = {
            user: {},
            loading: true,
            dataSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2 }),
            items: [],
        }
    }
    componentDidMount(){
        AsyncStorage.getItem('userData').then((user) => {
            let userData = JSON.parse(user)
            this.setState({
                user: userData,
            })
        })
        firebase.database().ref('Posts').limitToLast(10).on('value', (snap) => {
            console.log('new', snap.val())
            snap.forEach((child) => {
                this.state.items.push({
                    title: child.val().title,
                    key: child.key,
                    author: child.val().authorName,
                    image: child.val().picture,
                    price: child.val().price,
                    description: child.val().description,
                    stock: child.val().stock,
                    authorId: child.val().authorId
                });
            });
            this.setState({ 
                dataSource: this.state.dataSource.cloneWithRows(this.state.items),
                loading:false
            });
        });
    }

    logOut(){
        AsyncStorage.removeItem('userData').then(() => {
            firebase.auth().signOut();
                this.props.navigation.navigate('Index')
        })
    }

    renderRow(data) {
        return (
        <View style={styles.listProduct} key={data.key}>
            <TouchableOpacity 
             onPress={() => this.props.navigation.navigate('Detail', {data})}
            >
            <Text style={styles.titleProduct}> {data.title} </Text>
            <Text style={styles.textProduct}>{data.author}</Text>
            <Image
             source={{ uri:data.image }}
             style={{
                height: 150,
                width: 150,
                alignSelf: 'center',
            }}
          />
        </TouchableOpacity>
        <View style={styles.postInfo}>
          <Text style={styles.textProduct}>Rp.{data.price}</Text>
        </View>
        </View>
        )
    }

    render(){
        if (this.state.loading){
            return <ActivityIndicator size="large" />
        }

        console.ignoredYellowBox = ['Remote debugger'];
        console.ignoredYellowBox = ['Setting a timer'];
        console.log(this.state.user)
        const { navigate } = this.props.navigation
        return(
            <ScrollView>
            <View style={styles.container}>
                <View style={styles.header}>
                    <TouchableOpacity onPress={()=> this.props.navigation.navigate('Checkout')}>
                    <Icon name='md-cart' size={30} color='#eee'/>
                    </TouchableOpacity>
                    <View>
                    <TouchableOpacity onPress={this.logOut.bind(this)}>                    
                    <Icon name='ios-log-out-outline' size={30} color='#eee' />
                    </TouchableOpacity>
                    </View>

                    <View style={styles.addItem}>
                    <TouchableOpacity onPress={() => this.props.navigation.navigate('Add')}>
                    <Icon name='md-add' size={30} color='#eee' />
                    </TouchableOpacity>
                    </View>               
                </View>

                    <ListView
                      dataSource={this.state.dataSource}
                      renderRow={this.renderRow.bind(this)}
                      enableEmptySections={true}
                      />
            </View>
            </ScrollView>
        )
    }
}

1 个答案:

答案 0 :(得分:3)

卸载组件时,需要删除任何其他类型的侦听器的事件侦听器。 Firebase查询尝试在卸载组件时更新状态事件。您可以使用off方法删除firebase的侦听器。

您的代码的另一个可能问题是您正在直接操作状态值。这不是一个好习惯。下面的代码是一个示例,说明如何使用您正在尝试的方式实现类似的效果。

示例

onData = (snap) => {
  console.log('new', snap.val())
  snap.forEach((child) => {
    this.setState((prevState) => {
      const newState = Object.assign({}, prevState);
      newState.items.push({
        title: child.val().title,
        key: child.key,
        author: child.val().authorName,
        image: child.val().picture,
        price: child.val().price,
        description: child.val().description,
        stock: child.val().stock,
        authorId: child.val().authorId
      });
      return newState;
    });
  });
  this.setState({ 
    dataSource: this.state.dataSource.cloneWithRows(this.state.items),
    loading:false
  });
}

componentDidMount(){
    AsyncStorage.getItem('userData').then((user) => {
        let userData = JSON.parse(user)
        this.setState({
            user: userData,
        })
    })
    firebase.database().ref('Posts').limitToLast(10).on('value', this.onData );
}

componentWillUnmount() {
  firebase.database().ref('Posts').limitToLast(10).off('value', this.onData );
}