【发布时间】:2019-05-13 08:28:38
【问题描述】:
所以我根据这篇文章的理解: 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 端点中看到的所有内容:
当我执行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
【问题讨论】:
-
你能告诉我们
job的样子吗?也许在你的渲染函数中做一个 console.log -
@Tim,当我执行
console.log(job);时,它会呈现您在 API 端点中看到的所有内容,我将在上面粘贴。
标签: reactjs react-native