簡體   English   中英

在 static 方法中調用 setState 后應用程序崩潰

[英]App crashes after calling setState in static method

在 navigationOptions 中調用 setState 后,應用程序崩潰。 這只發生在 Android 設備上。 在我的崩潰代碼下方。

import React, { Component } from 'react';
import {
  Button,
  View,
  Platform,
  Text
} from 'react-native';
import { HeaderBackButton } from 'react-navigation-stack';

export default class Edit extends Component {
  static navigationOptions = ({ navigation: { state } }) => {
    return {
      title: 'add',
      gesturesEnabled: !state.params.isEditing,
      headerBackTitle: 'back',
      headerLeft: !state.params.isEditing(
        <HeaderBackButton
          backTitleVisible
          onPress={() => state.params.goBack()}
          title={Platform.OS === 'ios' ? 'back' : null}
        />
      ),
      headerRight: (
        <View style={Platform.OS !== 'ios' && { padding: 12 }}>
          {state.params.isEditing ? (
            <Button onPress={() => state.params.finishEditing()} title="done" />
          ) : (
            <Button onPress={() => state.params.beginEditing()} title="edit" />
          )}
        </View>
      ),
    };
  };

  state = {
    isLoading: true,
    isEditing: false,
    alreadyScanned: true,
  };

  componentDidMount() {
    this.setInitialState();
  }

  setInitialState = () => {
    const {
      navigation: {
        setParams,
        state: { params },
      },
      navigation,
    } = this.props;

    setParams({
      isEditing: this.state.isEditing,
      finishEditing: this.finishEditing,
      beginEditing: this.beginEditing,
      canGoBack: params.goBack,
      goBack: navigation.goBack,
    });
  };

  beginEditing = async () => {
    this.setState({
      isEditing: true,
    });
    await this.props.navigation.setParams({
      isEditing: true,
    });
  };

  finishEditing = async () => {
    this.setState({ isEditing: false });
    await this.props.navigation.setParams({
      isEditing: false,
    });
  };

  render() {
    const {isEditing} = this.state;
    return (
      <View
        style={{
          flex: 1,
          backgroundColor: isEditing ? 'green' : 'red'
        }}>
        <Text>is editing: {isEditing}</Text>
      </View>
    );
  }
}

我不太確定為什么這段代碼會使我的應用程序崩潰,因為它之前確實有效。

Expo Snack 由於某種原因無法解析 react-navigation 模塊。所以這是我的崩潰代碼。

項目依賴

  "dependencies": {
    "expo": "^35.0.0",
    "expo-asset": "~7.0.0",
    "expo-barcode-scanner": "~7.0.0",
    "expo-camera": "~7.0.0",
    "expo-constants": "~7.0.0",
    "expo-font": "~7.0.0",
    "expo-localization": "~7.0.0",
    "expo-permissions": "~7.0.0",
    "react": "16.11.0",
    "react-dom": "16.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
    "react-native-elements": "^1.2.6",
    "react-native-gesture-handler": "~1.3.0",
    "react-navigation": "^4.0.10",
    "react-navigation-stack": "^1.10.3",
  }

環境

您應該在設置參數之前驗證 this.props.navigation。

import React, { Component } from 'react';
import {
  Button,
  View,
  Platform,
  Text
} from 'react-native';
import { HeaderBackButton } from 'react-navigation-stack';

export default class Edit extends Component {
  static navigationOptions = ({ navigation: { state } }) => {
    return {
      title: 'add',
      gesturesEnabled: !state.params.isEditing,
      headerBackTitle: 'back',
      headerLeft: !state.params.isEditing(
        <HeaderBackButton
          backTitleVisible
          onPress={() => state.params.goBack()}
          title={Platform.OS === 'ios' ? 'back' : null}
        />
      ),
      headerRight: (
        <View style={Platform.OS !== 'ios' && { padding: 12 }}>
          {state.params.isEditing ? (
            <Button onPress={() => state.params.finishEditing()} title="done" />
          ) : (
            <Button onPress={() => state.params.beginEditing()} title="edit" />
          )}
        </View>
      ),
    };
  };

  state = {
    isLoading: true,
    isEditing: false,
    alreadyScanned: true,
  };

  componentDidMount() {
    this.setInitialState();
  }

  setInitialState = () => {
    if(this.props.navigation){
      const {
        navigation: {
          setParams,
          state: { params },
        },
        navigation,
      } = this.props;

      setParams({
        isEditing: this.state.isEditing,
        finishEditing: this.finishEditing,
        beginEditing: this.beginEditing,
        canGoBack: params.goBack,
        goBack: navigation.goBack,
      });
    }
  };

  beginEditing = async () => {
    this.setState({
      isEditing: true,
    });
    await this.props.navigation.setParams({
      isEditing: true,
    });
  };

  finishEditing = async () => {
    this.setState({ isEditing: false });
    await this.props.navigation.setParams({
      isEditing: false,
    });
  };

  render() {
    const { isEditing } = this.state;
    return (
      <View
        style={{
          flex: 1,
          backgroundColor: isEditing ? 'green' : 'red',
          justifyContent: 'center',
          alignItems: 'center'
        }}>
        <Text>is editing: {isEditing}</Text>
      </View>
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM