【问题标题】:Adjacent JSX elements must be wrapped in an enclosing tag, missing parent tag相邻的 JSX 元素必须包含在封闭标记中,缺少父标记
【发布时间】:2019-12-06 03:26:25
【问题描述】:

我正在尝试将 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 我尝试添加操作按钮,但我不断收到上述错误 如果您能具体说明缺少标记的位置以及应如何更正,这将非常有帮助 谢谢你

#

【问题讨论】:

    标签: reactjs react-native


    【解决方案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>
        );
    

    【讨论】:

      【解决方案2】:

      您的Agenda 组件和View 标签是相邻的,正如您在反应中知道的那样,我们只能在父标签上而不是相邻标签上。只需将它们包装在像这样的另一个视图标签中 -

      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>
          );
      

      【讨论】:

        【解决方案3】:

        省略道具和孩子,你有这个:

          return (
            <Agenda />
            <View />
          );
        

        这样返回两个组件是不合法的。您只需要在根目录中有一个 jsx 标记。 React 提供了一个special jsx tag called a "fragment",它唯一的工作就是包装多个组件。它不会在屏幕上产生任何输出:

          return (
            <React.Fragment>
              <Agenda />
              <View />
            </React.Fragment>
          );
        

        还有一个片段的快捷方式,只要您不需要向片段传递密钥就可以使用它:

          return (
            <>
              <Agenda />
              <View />
            </>
          );
        

        【讨论】:

          【解决方案4】:

          App.js。有两个兄弟/相邻组件AgendaView 组件。这些应该有一个父组件。 IE。 render() 函数应该有一个要呈现的组件。所以将AgendaView 包装在一个组件中。

          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',
            },);
          

          【讨论】:

            猜你喜欢
            • 2019-06-14
            • 2019-11-06
            • 2017-12-30
            • 2019-01-12
            • 2020-06-14
            • 2021-04-05
            • 2017-08-30
            • 1970-01-01
            相关资源
            最近更新 更多