React Native:不变违规:对象作为React子对象无效

时间:2019-05-13 08:28:39

标签: reactjs react-native

所以根据这篇文章我的理解是: React Redux: Uncaught Invariant Violation (Objects are not valid as a React child)

是我的{job.title}等是对象,React不会让我仅将对象放入渲染输出,但是我想我没有足够的经验来全面了解我为什么首先得到此错误,也没有解决方法。

因此在此屏幕中:

import React, { Component } from "react";
import { View, Text, Platform } from "react-native";
import { MapView } from "expo";
import { connect } from "react-redux";
import { Card, Button } from "react-native-elements";
import Swipe from "../components/Swipe";
import * as actions from "../actions";

class DeckScreen extends Component {
  renderCard(job) {
    return (
      <Card title={job.title}>
        <View style={{ height: 300 }}>
          <MapView
            scrollEnabled={false}
            style={{ flex: 1 }}
            cacheEnabled={Platform.OS === "android" ? true : false}
          />
        </View>
        <View style={styles.detailWrapper}>
          <Text>{job.company}</Text>
          <Text>{job.post_date.toString()}</Text>
        </View>
        <Text>
          {job.description.replace(/<span>/g, "").replace(/<\/span>/g, "")}
        </Text>
      </Card>
    );
  }

  renderNoMoreCards() {
    return <Card title="No more jobs" />;
  }

  render() {
    return (
      <View>
        <Swipe
          data={this.props.jobs}
          renderCard={this.renderCard}
          renderNoMoreCards={this.renderNoMoreCards}
          keyProp="id"
        />
      </View>
    );
  }
}

const styles = {
  detailWrapper: {
    flexDirection: "row",
    justifyContent: "space-around",
    marginBottom: 10
  }
};

function mapStateToProps({ jobs }) {
  return { jobs: jobs.listing };
}

export default connect(
  mapStateToProps,
  actions
)(DeckScreen);

以及在我的组件中:

import React, { Component } from "react";
import {
  View,
  Animated,
  PanResponder,
  Dimensions,
  LayoutAnimation,
  UIManager
} from "react-native";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SWIPE_THRESHOLD = 0.25 * SCREEN_WIDTH;
const SWIPE_OUT_DURATION = 250;

class Swipe extends Component {
  static defaultProps = {
    onSwipeRight: () => {},
    onSwipeLeft: () => {},
    keyProp: "id"
  };

  constructor(props) {
    super(props);

    const position = new Animated.ValueXY();
    const panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (event, gestureState) => true,
      onPanResponderMove: (event, gestureState) => {
        position.setValue({ x: gestureState.dx, y: gestureState.dy });
      },
      onPanResponderRelease: (event, gestureState) => {
        if (gestureState.dx > SWIPE_THRESHOLD) {
          this.forceSwipe("right");
        } else if (gestureState.dx < -SWIPE_THRESHOLD) {
          this.forceSwipe("left");
        } else {
          this.resetPosition();
        }
      }
    });

    this.state = { panResponder, position, index: 0 };
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.data !== this.props.data) {
      this.setState({ index: 0 });
    }
  }

  componentWillUpdate() {
    UIManager.setLayoutAnimationEnabledExperimental &&
      UIManager.setLayoutAnimationEnabledExperimental(true);
    LayoutAnimation.spring();
  }

  forceSwipe(direction) {
    const x = direction === "right" ? SCREEN_WIDTH : -SCREEN_WIDTH;
    Animated.timing(this.state.position, {
      toValue: { x, y: 0 },
      duration: SWIPE_OUT_DURATION
    }).start(() => this.onSwipeComplete(direction));
  }

  onSwipeComplete(direction) {
    const { onSwipeLeft, onSwipeRight, data } = this.props;
    const item = data[this.state.index];
    direction === "right" ? onSwipeRight(item) : onSwipeLeft(item);
    this.state.position.setValue({ x: 0, y: 0 });
    this.setState({ index: this.state.index + 1 });
  }

  resetPosition() {
    Animated.spring(this.state.position, {
      toValue: { x: 0, y: 0 }
    }).start();
  }

  getCardStyle() {
    const { position } = this.state;
    const rotate = position.x.interpolate({
      inputRange: [-SCREEN_WIDTH * 1.5, 0, SCREEN_WIDTH * 1.5],
      outputRange: ["-120deg", "0deg", "120deg"]
    });
    return {
      ...position.getLayout(),
      transform: [{ rotate }]
    };
  }

  renderCards() {
    if (this.state.index >= this.props.data.length) {
      return this.props.renderNoMoreCards();
    }
    return this.props.data
      .map((item, i) => {
        if (i < this.state.index) {
          return null;
        }
        if (i === this.state.index) {
          return (
            <Animated.View
              key={item[this.props.keyProp]}
              style={[this.getCardStyle(), styles.cardStyle]}
              {...this.state.panResponder.panHandlers}
            >
              {this.props.renderCard(item)}
            </Animated.View>
          );
        }
        return (
          <Animated.View
            key={item[this.props.keyProp]}
            style={[styles.cardStyle, { top: 10 * (i - this.state.index) }]}
          >
            {this.props.renderCard(item)}
          </Animated.View>
        );
      })
      .reverse();
  }

  render() {
    return <View>{this.renderCards()}</View>;
  }
}

const styles = {
  cardStyle: {
    position: "absolute",
    width: SCREEN_WIDTH
  }
};

export default Swipe;

当我执行console.log(job);时,它将呈现您在API端点中看到的所有内容:

enter image description here

当我做console.log(job.title);时,我得到了:

[03:46:03] Front End Designer Summer Internship
[03:46:03] Senior UX / Product Designer - Investments AI team
[03:46:03] Technical AV Analyst
[03:46:03] Senior Designer
[03:46:03] Junior Developer
[03:46:03] Webinar Producer + Host
[03:46:03] Front End Web Developer
[03:46:03] Android Developer needed for React Native project
[03:46:03] UX Designer
[03:46:03] Software Product Engineer - Reinventing VC

1 个答案:

答案 0 :(得分:0)

沿着做console.log(job);的过程,我决定再做console.log(job.title);,然后我回来了:

[03:46:03] Front End Designer Summer Internship
[03:46:03] Senior UX / Product Designer - Investments AI team
[03:46:03] Technical AV Analyst
[03:46:03] Senior Designer
[03:46:03] Junior Developer
[03:46:03] Webinar Producer + Host
[03:46:03] Front End Web Developer
[03:46:03] Android Developer needed for React Native project
[03:46:03] UX Designer
[03:46:03] Software Product Engineer - Reinventing VC

所以这不是问题,然后我决定继续前进并做一个console.log(job.company);,然后我回来了:

[03:48:25] Object {
[03:48:25]   "id": "planningcenter",
[03:48:25]   "location": Object {
[03:48:25]     "id": "carlsbadca",
[03:48:25]     "name": "Carlsbad, CA",
[03:48:25]   },
[03:48:25]   "logo": "https://d2fcz5no062gar.cloudfront.nethttps://authenticjobs.s3.amazonaws.com/uploads/logos/edc867ddb3b30a5c8f8819d1a1347346/thumb/PC -Icon -- color .png",
[03:48:25]   "name": "Planning Center",
[03:48:25]   "tagline": "Software designed to help church volunteers",
[03:48:25]   "type": null,
[03:48:25]   "url": "http://planning.center",
[03:48:25] }
[03:48:26] Object {
[03:48:26]   "id": "americaninternationalgroupaig",
[03:48:26]   "location": Object {
[03:48:26]     "id": "175waterstreetnewyorkny10038",
[03:48:26]     "name": "175 Water Street New York, NY 10038",
[03:48:26]   },
[03:48:26]   "logo": "https://d2fcz5no062gar.cloudfront.net/assets/images/defaults/company-blank.png",
[03:48:26]   "name": "American International Group (AIG)",
[03:48:26]   "tagline": "We're a 100 year old insurance company with operations globally!",
[03:48:26]   "type": null,
[03:48:26]   "url": "https://www.aig.com/about-us",
[03:48:26] }
[03:48:26] Object {
[03:48:26]   "id": "universityofcalifornialosangeles",
[03:48:26]   "location": Object {
[03:48:26]     "id": "losangelesca",
[03:48:26]     "name": "Los Angeles, CA",

宾果!出现了问题,返回了{job.company}上的对象,所以我决定尝试console.log(job.company.id);并得到:

[03:49:14] planningcenter
[03:49:15] americaninternationalgroupaig
[03:49:15] universityofcalifornialosangeles
[03:49:15] whitneymuseumofamericanart
[03:49:15] studioality
[03:49:15] convertkit
[03:49:15] metropolitanareaplanningcouncil
[03:49:15] jenzy
[03:49:15] cfainstitute
[03:49:15] nfx

轰!问题解决了,我的UI正在呈现。