在尝试将第二个组件加载到我的app.js中时感到沮丧。我也有一个叫。我不断收到此错误,但我不明白为什么。 :
无法加载 捆绑包(http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false) 出现错误:(SyntaxError: /Users/vemundeldegard/AwesomeProject/app/screens/Home.js:相邻JSX 元素必须包装在封闭标签中。您想要JSX吗 片段<> ...? (199:6)
将其加载到我的app.js中
import Comments from '../components/Comments'
<Comments
addComment=""
/>
组件文件如下:
const Comments = (props) => {
const styles = StyleSheet.create({
container: {
paddingLeft: 15,
paddingRight: 15,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
},
button: {
padding: 10,
height: 30,
backgroundColor: "#eee"
},
buttonText: {
fontSize:11
},
field: {
fontSize:13,
position: "relative",
left: -3,
top: -10,
}
});
return (
<View style={styles.container}>
<Input style={styles.field}
autoCorrect={false}
autoCapitalize="none"
placeholder="Skriv en kommentar..."
/>
<Button rounded style={styles.button} onPress={() => props.addComment()}>
<Text style={styles.buttonText}>Kommenter</Text>
</Button>
</View>
)
}
export Comments;
Whole app.js
import React, { Component } from 'react';
import * as firebase from 'firebase';
import {
Alert,
StyleSheet,
Text,
View,
FlatList,
ScrollView,
Modal,
TouchableHighlight,
RefreshControl,
Image
} from 'react-native';
import { Icon, Textarea, Container, Form, Content, Button, Input, Item, Label } from 'native-base';
import { firestore, settings } from '../Fire';
import moment from 'moment';
import Swiper from 'react-native-swiper';
import { RenderImage } from '../components/RenderImage'
import { Post } from '../components/Post'
import Comments from '../components/Comments'
export default class Home extends Component {
constructor(props){
super(props);
this.state = {
getData: [],
liked: false,
displayName:''
}
this.ref = firestore.collection("tips").orderBy("date", "desc");
}
state = { currentUser: null }
signOutUser = () => {
firebase.auth().signOut().then(function() {
console.log("user signed out")
}).catch(function(error) {
console.log(error.toString())
});
}
deleteAccount = () => {
firebase.auth().currentUser.delete().then(function () {
console.log('delete successful?')
console.log(app.auth().currentUser)
}).catch(function (error) {
console.error({error})
})
}
updateUser = (displayName) => {
var user = firebase.auth().currentUser;
let date = new moment().format("YYYYMMDD HHmmss");
user.updateProfile({
displayName: displayName,
lastUpdated: date
}).then(function() {
alert("Updated!")
}).catch(function(error) {
alert("Error!")
});
}
newTips = () => {
let user = firebase.auth().currentUser;
let name, email, photoUrl, uid, emailVerified, currentUser, displayName;
let date = new moment().format("YYYYMMDD HHmmss");
let tips=this.state.tips;
firebase.auth().onAuthStateChanged(user => {
if (user) {
email = user.displayName;
// User is signed in.
console.log('Logged in user: ' + email)
firestore.collection("tips").add({
user: user.displayName,
date: date,
tips: tips,
like: 0,
})
.then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
} else {
// User is signed out.
console.log('No user signed in')
}
})
}
componentDidMount(){
this.getItems();
const { currentUser } = firebase.auth();
this.setState({ currentUser });
}
getItems = async () => {
this.setState({ refreshing: true });
this.unsubscribe = await this.ref.onSnapshot((querySnapshot) => {
const todos = [];
querySnapshot.forEach((doc) => {
todos.push({
id: doc.id,
tips: doc.data().tips,
date: doc.data().date,
user: doc.data().user,
like: doc.data().like,
})
this.ref.get().then(function(documentSnapshot) {
// check and do something with the data here.
});
})
this.setState({
refreshing: false,
getData: todos
})
})
}
likePost = (author, id) => {
let user = firebase.auth().currentUser;
let name, email, photoUrl, uid, emailVerified, currentUser, displayName;
let date = new moment().format("YYYYMMDD HHmmss");
firestore.collection("tips").doc(id).update({
likes: {
user: user.uid
}
})
.then(function() {
alert("Liked the post " + id)
})
.catch(function(error) {
alert("Error writing document: ", user.uid, error);
});
this.liked()
}
liked(){
this.setState({
liked: !this.state.liked
})
}
deletePost = (author, id) => {
let user = firebase.auth().currentUser;
const { currentUser } = this.state;
const currentUsername = currentUser && currentUser.displayName;
if (currentUsername == author) {
Alert.alert(
'Er du sikker?',
'Du sletter nå denne posten...',
[
{text: 'Nei', onPress: () => {
}, style: 'cancel'},
{text: 'Ja', onPress: () => {
firestore.collection("tips").doc(id).delete().then(function() {
alert("Posten er slettet!")
}).catch(function(error) {
alert("Error removing document: ", error);
});
}},
]
);
}
else {
alert("Not your post " + currentUsername + " its " + author)
}
}
viewComments = () => {
alert("View Comments!!")
}
renderItem = ({ item, index }) => {
return (
<View>
<Post
author={item.user}
date={ moment(item.date).fromNow() }
entry={item.tips}
likes={item.like}
id={item.id}
image="https://i.pinimg.com/originals/c5/89/19/c589198a4e4a4b2b54ebb3852ea4bd8b.jpg"
commentCount="123"
like={this.likePost}
delete={this.deletePost}
goComments={this.viewComments}
liked={this.state.liked}
/>
<Comments
addComment=""
/>
</View>
)
}
_renderEmpty= () => {
return (
<Text>There is no tips...</Text>
)
}
_renderFooter = () => {
return (
<Text>All tips has been loaded...</Text>
)
}
_keyExtractor = (item, index) => item.id;
_onRefresh = () => this.getItems();
state = {
modalVisible: false,
refreshing: true, // whether comments list is being refreshed or not
};
render() {
const { currentUser } = this.state
return (
<Swiper
loop={false}
showsPagination={false}
index={1}
ref='swiper'
>
<View style={share.container}>
<Form>
<Textarea
ref= {(el) => { this.tips = el; }}
onChangeText={(tips) => this.setState({tips})}
value={this.state.tips}
placeholderTextColor={'#FFF'}
style={{ fontSize: 38, color: '#FFF'}}
rowSpan={10}
placeholder="Share your best vegan tips with people near you.."
adjustsFontSizeToFit={true}
/>
<Button
rounded
style={form.button}
onPress={() => {
this.newTips()
this.refs.swiper.scrollBy(1)
}
}
>
<Text style={{color: '#FFF'}}>Share</Text>
</Button>
</Form>
</View>
<View style={styles.container}>
<FlatList style={styles.flatlist}
data={this.state.getData}
renderItem={this.renderItem}
ListEmptyComponent={this._renderEmpty}
ListFooterComponent={this._renderFooter}
keyExtractor={this._keyExtractor}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
/>
}
>
</FlatList>
</View>
<View>
<Text>3</Text>
</View>
</Swiper>
);
}
}
const profile = StyleSheet.create({
container: {
backgroundColor: '#EEF2E8',
flex:1,
paddingTop: 40,
padding: 10,
}
})
const title = StyleSheet.create({
h1: {
fontSize:32,
color: "#70B21B",
paddingLeft: 8,
marginBottom: 10,
}
})
const form = StyleSheet.create({
input: {
marginRight: 15,
},
button: {
backgroundColor: '#ADDF6F',
color: '#FFF',
fontWeight: '600',
paddingLeft: 20,
paddingRight: 20,
marginTop: 15,
marginLeft: 10,
marginRight: 10,
}
})
const share = StyleSheet.create({
container: {
backgroundColor: '#D0E8B2',
flex:1,
paddingTop: 40,
padding: 10,
}
})
const modal = StyleSheet.create({
container: {
flex:1,
padding: 10,
backgroundColor:'rgba(255,255,255,0.8)',
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center',
}
})
const styles = StyleSheet.create({
container: {
backgroundColor: '#FFF'
},
flatlist: {
},
})
答案 0 :(得分:1)
javascript中的函数每次调用只能返回一个数据结构。将JSX语法中的每个元素都视为一个函数,因为这就是它们的本质。您需要返回一个元素(函数)或一个元素数组(一个函数数组)。在React 16之前,解决此错误的方法是将每组元素包装在div中。要么返回一个元素数组(但必须提供一个键)。如果您使用的是React16,则可以使用Fragment
。他们看起来像这样。
import React, { Fragment } from 'react;
class Hello extends React.Component {
render() {
return (
<Fragment>
<h1>Hello</h1>
<h2>World</h2>
</Fragment>
);
}
}
这样,您就不必在不需要的DOM上添加额外的标记。
答案 1 :(得分:0)
React希望您以某种方式构造JSX。将<div>
标记中的内容包装起来。
答案 2 :(得分:0)
错误基本上表明React希望将JSX元素包含在一个JSX元素中:div,span等。
但是,有几种方法可以达到期望的结果:
旧方法(反应15及以下-使用跨度):
<span>
<Input
style={styles.field}
autoCorrect={false}
autoCapitalize="none"
placeholder="Skriv en kommentar..."
/>
<Button
rounded
style={styles.button}
onPress={() => props.addComment()}
>
<Text style={styles.buttonText}>Kommenter</Text>
</Button>
</span>
反应16岁以上(<Fragment> ... </Fragment>
):
<Fragment>
<Input
style={styles.field}
autoCorrect={false}
autoCapitalize="none"
placeholder="Skriv en kommentar..."
/>
<Button
rounded
style={styles.button}
onPress={() => props.addComment()}
>
<Text style={styles.buttonText}>Kommenter</Text>
</Button>
</Fragment>
反应16岁以上([ array with keys ]
):
[
<Input
key="comment-input"
style={styles.field}
autoCorrect={false}
autoCapitalize="none"
placeholder="Skriv en kommentar..."
/>,
<Button
rounded
key="add-comment-button"
style={styles.button}
onPress={() => props.addComment()}
>
<Text style={styles.buttonText}>Kommenter</Text>
</Button>
]