React Native:警告:失败的prop类型:AutoHeightWebView:prop类型`source`无效;

时间:2019-05-23 04:33:36

标签: react-native

我在一个名为Details的屏幕上进行了测试:

export class Details extends Component {
  static propTypes = {
    auth: PropTypes.object,
    checkingUserMembership: PropTypes.bool,
    checkUserMembership: PropTypes.func,
    fetchSelectedEvent: PropTypes.func,
    isLapsedMember: PropTypes.bool,
    isMember: PropTypes.bool,
    loadingSelectedEvent: PropTypes.bool,
    navigation: PropTypes.object,
    primaryIndividual: PropTypes.object,
    selectedEvent: PropTypes.object,
    selectedPrice: PropTypes.object,
    setSelectedPrice: PropTypes.func,
    userKey: PropTypes.string,
    userOrganization: PropTypes.object,
  };

  static navigationOptions = ({navigation}) => ({
    title: navigation.state.params.title,
  });

  constructor(props) {
    super(props);
    const prices = getDetailPrices(this.props);
    this.state = {
      userOpenedMemberLink: false,
      appState: AppState.currentState,
      ...prices,
    };
  }

  componentDidMount() {
    this.props.fetchSelectedEvent();
    this.props.checkUserMembership();
    AppState.addEventListener('change', this._handleAppStateChange);

    if (this.props.isMember && !this.props.isLapsedMember) {
      this._selectMemberPrice();
    }
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this._handleAppStateChange);
  }

  _selectMemberPrice = () => {
    const price = this.state.individualPrices.find(p => p.IsMemberPrice);
    if (price) {
      this.props.setSelectedPrice(price);
    }
  };

  _handleAppStateChange = async appState => {
    if (
      this.state.appState.match(/inactive|background/) &&
      appState === 'active'
    ) {
      this.props.checkUserMembership();
    }
  };

  _validateCapacity = selectedEvent => {
    if (selectedEvent.NumberOfSeatsAvailable === 0) {
      Alert.alert(
        'Capacity Exceeded',
        capacityLimit,
        [
          {
            text: 'OK',
            onPress: () => false,
            style: 'cancel',
          },
        ],
        {cancelable: false}
      );

      return false;
    }

    return true;
  };

  _alertNoTableSeats = () => {
    Alert.alert(
      'Capacity Exceeded',
      capacityLimitTable,
      [
        {
          text: 'OK',
          onPress: () => false,
          style: 'cancel',
        },
      ],
      {cancelable: false}
    );
  };

  _navigate = () => {
    const {selectedEvent, isMember, selectedPrice, isLapsedMember} = this.props;
    const hasSeats = this._validateCapacity(selectedEvent);

    if (hasSeats) {
      if (selectedEvent.IsFree) {
        //eslint-disable-next-line
        if (selectedEvent.IsMembersOnly && (!isMember || isLapsedMember)) {
          this._alertMembershipIssue();
        } else {
          this.props.navigation.navigate('EventRegistration');
        }
      } else if (selectedPrice) {
        //eslint-disable-next-line
        this.props.navigation.navigate("EventRegistration");
      } else {
        Alert.alert(
          'Event Pricing',
          'Please select a price before continuing.',
          [
            {
              text: 'OK',
              onPress: () => false,
              style: 'cancel',
            },
          ],
          {cancelable: false}
        );
      }
    }
  };

  _loginAsMember = (price = null) => {
    this.props.navigation.navigate('MembershipConfirmation', {price});
  };

  _canSelectPrice = price => {
    if (price.IsMemberPrice && this.props.isLapsedMember) {
      return false;
    }

    if (!this.props.isMember && price.IsMemberPrice) {
      return false;
    }

    return true;
  };

  _tableSeatsAvailable = price => {
    if (
      price.IsTable &&
      this.props.selectedEvent.NumberOfSeatsAvailable < price.NumberOfSeats
    ) {
      return false;
    }
    return true;
  };

  _selectPrice = async price => {
    const canSelect = this._canSelectPrice(price);
    if (canSelect) {
      const tableSeatsAvailable = this._tableSeatsAvailable(price);
      if (tableSeatsAvailable) {
        this.props.setSelectedPrice(price);
      } else {
        this._alertNoTableSeats();
      }
    } else {
      this._alertMembershipIssue(price);
    }
  };

  _alertMembershipIssue = (price = null) => {
    const {isLapsedMember, userKey} = this.props;
    const buttons = [
      {
        text: isLapsedMember ? 'Renew Membership' : 'Join NFIB',
        onPress: () => {
          let url = `${env.membershipJoinLink}=${userKey}`;
          if (isLapsedMember) {
            const {userOrganization, primaryIndividual} = this.props;
            const {PostalCode: zip} = userOrganization.Addresses[0];
            const lastName = primaryIndividual.PersonalDetails.LastName;
            const memberID = userOrganization.Id;
            //prettier-ignore
            url = `${env.membershipRenewLink}?lname=${lastName}&mid=${memberID}&zip=${zip}`;
          }
          Linking.openURL(url);
          this.setState({userOpenedMemberLink: true});
        },
      },
      {
        text: 'Cancel',
        onPress: () => false,
        style: 'cancel',
      },
    ];

    if (!isLapsedMember) {
      buttons.unshift({
        text: 'I am a Member',
        onPress: () => this._loginAsMember(price),
      });
    }

    Alert.alert(
      isLapsedMember ? 'Renew Membership' : 'Members Only',
      memberMsg,
      buttons,
      {cancelable: false}
    );
  };

  render() {
    if (this.props.loadingSelectedEvent) {
      return <Loading />;
    }

    return (
      <EventDetails
        event={this.props.selectedEvent}
        handleRegistrationButtonPress={this._navigate}
        handleSelectPrice={this._selectPrice}
        tablePrices={this.state.tablePrices}
        individualPrices={this.state.individualPrices}
        selectedPrice={this.props.selectedPrice}
        checkingUserMembership={this.props.checkingUserMembership}
      />
    );
  }
}

DetailsEventDetails的父级,并且有一个名为PhoneEventDescription的兄弟姐妹,如下所示:

import React from 'react';
import styles from 'events/styles';
import {View, Text} from 'react-native';
import PropTypes from 'prop-types';
import {Card, WebViewAutoHeight} from 'common-components';
import {feedContentStyles} from 'theme';
import PriceRow from './PriceRow';
import {moderateScale} from 'react-native-size-matters';

const propTypes = {
  event: PropTypes.object.isRequired,
  handleSelectPrice: PropTypes.func.isRequired,
  individualPrices: PropTypes.arrayOf(PropTypes.object),
  selectedPrice: PropTypes.object,
  tablePrices: PropTypes.arrayOf(PropTypes.object),
};

//prettier-ignore
const getHTML = event => `<body style="font-family: -apple-system, Roboto, sans-serif; font-size: ${moderateScale(14, 0.2)}px;">${event.LongDescription}</body>`;

const PhoneEventDescription = props => {
  const {
    event,
    handleSelectPrice,
    individualPrices,
    selectedPrice,
    tablePrices,
  } = props;

  const displayPrices =
    !event.IsRestricted &&
    !event.IsFree &&
    (individualPrices.length > 0 || tablePrices.length > 0);

  return (
    <View style={{flex: 1}}>
      <Card style={styles.cardStyles} tappable={false}>
        <Text style={styles.contentTitle}>{'Description'}</Text>
        {event.LongDescription ? (
          <WebViewAutoHeight
            source={{
              html: getHTML(event),
            }}
          />
        ) : (
          <Text style={feedContentStyles.parragraph}>
            {event.ShortDescription}
          </Text>
        )}
      </Card>

该子组件导致了此错误:

 Warning: Failed prop type: AutoHeightWebView: prop type `source` is invalid; it must be a function, usually from the `prop-types` package, but received `undefined`.

Warning: Stateless function components cannot be given refs. Attempts to access this ref will fail.

AutoHeightWebView的来源是什么?这是什么警告,我该如何解决?

似乎它引用了以下软件包:"react-native-autoheight-webview": "0.6.1",,但是这里到底有什么问题呢?我对这个软件包不熟悉。

它是从此处的WebViewAutoHeight通用组件导入的:

import React from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, Dimensions} from 'react-native';
import AutoHeightWebView from 'react-native-autoheight-webview';
const {width} = Dimensions.get('window');

const WebViewAutoHeight = props => (
  <AutoHeightWebView
    style={[styles.webview, props.style ? props.style : {}]}
    {...props}
  />
);

const styles = StyleSheet.create({
  webview: {
    width: width - 31,
  },
});

WebViewAutoHeight.propTypes = {
  source: PropTypes.object.isRequired,
  style: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
};

export {WebViewAutoHeight};

1 个答案:

答案 0 :(得分:0)

我可能是WebViewAutoHeight组件react-native-autoheight-webview npm软件包。 只需检查您的package.json文件即可。