我正在尝试将 action buttons 添加到我的 shedule 应用
源代码
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
import {Agenda} from 'react-native-calendars';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/Ionicons';
export default class AgendaScreen extends Component {
constructor(props) {
super(props);
this.state = {
items: {}
};
}
render() {
return (
<Agenda
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2017-05-16'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
/>
<View style={{flex:1, backgroundColor: '#f3f3f3'}}>
{/* Rest of the app comes ABOVE the action button component !*/}
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="Create Shedule" onPress={() => console.log("Create Shedule!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#3498db' title="Notifications" onPress={() => {}}>
<Icon name="md-notifications-off" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#1abc9c' title="All Tasks" onPress={() => {}}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
);
this.confirmDate = this.confirmDate.bind(this);
this.openCalendar = this.openCalendar.bind(this);
}
loadItems(day) {
setTimeout(() => {
for (let i = -15; i < 85; i++) {
const time = day.timestamp + i * 24 * 60 * 60 * 1000;
const strTime = this.timeToString(time);
if (!this.state.items[strTime]) {
this.state.items[strTime] = [];
const numItems = Math.floor(Math.random() * 5);
for (let j = 0; j < numItems; j++) {
this.state.items[strTime].push({
name: 'Item for ' + strTime,
height: Math.max(50, Math.floor(Math.random() * 150))
});
}
}
}
//console.log(this.state.items);
const newItems = {};
Object.keys(this.state.items).forEach(key => {newItems[key] = this.state.items[key];});
this.setState({
items: newItems
});
}, 1000);
// console.log(`Load Items for ${day.year}-${day.month}`);
}
renderItem(item) {
return (
<View style={[styles.item, {height: item.height}]}><Text>{item.name}</Text></View>
);
}
renderEmptyDate() {
return (
<View style={styles.emptyDate}><Text>This is empty date!</Text></View>
);
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
}
const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
flex: 1,
borderRadius: 5,
padding: 10,
marginRight: 10,
marginTop: 17
},
emptyDate: {
height: 15,
flex:1,
paddingTop: 30
}
}
actionButtonIcon: {
fontSize: 20,
height: 22,
color: 'white',
},);
这是我的操作按钮源代码(也包含在上面 代码)
import React, { Component } from 'react';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/Ionicons';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={{flex:1, backgroundColor: '#f3f3f3'}}>
{/* Rest of the app comes ABOVE the action button component !*/}
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="Create Shedule" onPress={() => console.log("Create Shedule!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#3498db' title="Notifications" onPress={() => {}}>
<Icon name="md-notifications-off" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#1abc9c' title="All Tasks" onPress={() => {}}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
);
}
const styles = StyleSheet.create({
actionButtonIcon: {
fontSize: 20,
height: 22,
color: 'white',
},
});
从here中可以获取日历,这就是action button 我尝试添加操作按钮,但始终收到上述错误 如果您能明确指出标签丢失的位置以及如何纠正标签,这将非常有帮助 谢谢
#答案 0 :(得分:1)
您的Agenda
组件和View
标签是相邻的,正如您所知道的,在react中,我们只能在父标签上使用,而没有相邻的标签。只需将它们包装在另一个这样的视图标签中-
render() {
return (
<View>
<Agenda
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2017-05-16'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
/>
<View style={{flex:1, backgroundColor: '#f3f3f3'}}>
{/* Rest of the app comes ABOVE the action button component !*/}
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="Create Shedule" onPress={() => console.log("Create Shedule!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#3498db' title="Notifications" onPress={() => {}}>
<Icon name="md-notifications-off" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#1abc9c' title="All Tasks" onPress={() => {}}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
</View>
);
答案 1 :(得分:1)
省略道具和孩子,您会得到:
return (
<Agenda />
<View />
);
返回这样的两个组件是不合法的。您只需要在根目录有一个jsx标记即可。 React提供了一个special jsx tag called a "fragment",他的唯一工作就是包装多个组件。它不会在屏幕上产生任何输出:
return (
<React.Fragment>
<Agenda />
<View />
</React.Fragment>
);
还有一个片段的快捷方式,只要不需要将密钥传递给片段,就可以使用该快捷方式:
return (
<>
<Agenda />
<View />
</>
);
答案 2 :(得分:1)
在App.js
中。有两个同级/相邻组件Agenda
和View
组件。这些应具有单个父组件。即render()
函数应具有单个要呈现的组件。因此,将Agenda
和View
包装在一个组件中。
import {
Text,
View,
StyleSheet
} from 'react-native';
import {Agenda} from 'react-native-calendars';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/Ionicons';
export default class AgendaScreen extends Component {
constructor(props) {
super(props);
this.state = {
items: {}
};
}
render() {
return (
<>
<Agenda
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2017-05-16'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
/>
<View style={{flex:1, backgroundColor: '#f3f3f3'}}>
{/* Rest of the app comes ABOVE the action button component !*/}
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="Create Shedule" onPress={() => console.log("Create Shedule!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#3498db' title="Notifications" onPress={() => {}}>
<Icon name="md-notifications-off" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#1abc9c' title="All Tasks" onPress={() => {}}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
</>
);
this.confirmDate = this.confirmDate.bind(this);
this.openCalendar = this.openCalendar.bind(this);
}
loadItems(day) {
setTimeout(() => {
for (let i = -15; i < 85; i++) {
const time = day.timestamp + i * 24 * 60 * 60 * 1000;
const strTime = this.timeToString(time);
if (!this.state.items[strTime]) {
this.state.items[strTime] = [];
const numItems = Math.floor(Math.random() * 5);
for (let j = 0; j < numItems; j++) {
this.state.items[strTime].push({
name: 'Item for ' + strTime,
height: Math.max(50, Math.floor(Math.random() * 150))
});
}
}
}
//console.log(this.state.items);
const newItems = {};
Object.keys(this.state.items).forEach(key => {newItems[key] = this.state.items[key];});
this.setState({
items: newItems
});
}, 1000);
// console.log(`Load Items for ${day.year}-${day.month}`);
}
renderItem(item) {
return (
<View style={[styles.item, {height: item.height}]}><Text>{item.name}</Text></View>
);
}
renderEmptyDate() {
return (
<View style={styles.emptyDate}><Text>This is empty date!</Text></View>
);
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
}
const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
flex: 1,
borderRadius: 5,
padding: 10,
marginRight: 10,
marginTop: 17
},
emptyDate: {
height: 15,
flex:1,
paddingTop: 30
}
}
actionButtonIcon: {
fontSize: 20,
height: 22,
color: 'white',
},);
答案 3 :(得分:1)
始终将多个组件或标签包装在父/包装器中
喜欢-
return(
<View>
<Component1 />
<Component2 />
</View>
)
不是这样
return(
<Component1 />
<Component2 />
)
在您的代码中
由父View
标签包裹
return (
<View>
<Agenda
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2017-05-16'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
/>
<View style={{flex:1, backgroundColor: '#f3f3f3'}}>
{/* Rest of the app comes ABOVE the action button component !*/}
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="Create Shedule" onPress={() => console.log("Create Shedule!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#3498db' title="Notifications" onPress={() => {}}>
<Icon name="md-notifications-off" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item buttonColor='#1abc9c' title="All Tasks" onPress={() => {}}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
</View>
);