简体   繁体   English

警告:React.createElement:在组件中使用组件时类型无效

[英]Warning: React.createElement: type is invalid when using a component in a component

Okay I have an issue which has stumped me for hours now and I cannot for the life of me see what the issue is.好的,我有一个问题困扰了我好几个小时,我一生都无法看到问题所在。

This is happening because of renderGuestOptions being used as a component in renderGuestPrices.这是因为 renderGuestOptions 被用作 renderGuestPrices 中的一个组件。 The odd thing is if I change it from being an arrow function to a normal function() {} then it works, but then I cannot access 'this' to update the state.奇怪的是,如果我将它从箭头 function 更改为正常的 function() {} 那么它可以工作,但是我无法访问“this”来更新 state。

I'm only using React and ReactDOM and I'm not using any exports or as such.我只使用 React 和 ReactDOM,我没有使用任何导出或类似的东西。

Error Text: Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined.错误文本:警告:React.createElement:类型无效——需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:未定义。 You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。

import React from 'react';
import ReactDOM from 'react-dom'
class TimeSlots extends React.Component {
constructor(props) {
    super(props);
    this.telephone = getCalendarWrapper().dataset.telephone;
    // this.timeSlotButtons = React.createRef();
    // this.monthPrevious = React.createRef();
    // this.monthPreviousByYear = React.createRef();
    // this.monthForward = React.createRef();
    // this.monthForwardByYear = React.createRef();
    this.state = {
        currentDate: this.props.currentDate,
        timesAvailable: this.props.timesAvailable,
        guests: null,
        guestsSelected: null,
        timeSlotSelected: null,
        bookingModal: {
            show: false
        },
    }

    console.log(this.props.roomSlug);
    console.log(this.props.currentDate);
    console.log(this.props.timesAvailable);
}
// -----------------
// -- RENDERS GUEST OPTIONS WHEN USER HAS CLICKED A TIME SLOT
// -----------------
renderGuestOptions = (props) => {
// renderGuestOptions(props) {
    // const guestDataTest = props.guestData.guestData;
    const guestData = props.guestData;
    console.log(this);

    if (guestData) {
        return(
            // onChange we update the guestSelected state, which will then be used in the ajax request if its added
            <select className="form-control" onChange={(event) => console.log(event.target.value)}>
            {/* <select className="form-control" onChange={(event) => this.setState({guestsSelected: event.target.value})}> */}
                {Object.keys(guestData).map(function(key) {
                    return <option key={key} value={key}>{key} People - £{guestData[key]}</option>
                })}
            </select>
        );
    } else {
        return <h2>Sorry no times are available</h2>;
    }
}

renderGuestPrices = () => {
    if (!this.state.timeSlotSelected && !this.state.guests) {
        return <div></div>;
    }

    return(
        <form className="timeslot row" onSubmit={this.formSubmitHandler}>
            <div className="col-12 mb-3 text-center">
                <span className="title title--h2">How Many Guests?</span>
            </div>
            <div className="col-12 mb-3 mb-md-4">
                <this.renderGuestOptions guestData={this.state.guests} />
            </div>
            <div className="col-12 text-center mb-3 mb-md-4">
                <div className="room-calendar__timeslots__help">

                    <a href={"tel:" + this.telephone.replace(/ /g, '')}><i className="fa fa-phone"></i> {this.telephone}</a>
                </div>
            </div>
            <div className="col-12">
                <div className="d-block px-4">
                    <button className="btn d-block w-100 mb-3" type="submit">Add To Basket</button>
                    {/* <span className="btn d-block mb-3" onClick={() => this.addToBasketHandler()}>Add To Basket</span> */}
                    <button className="btn d-block w-100" type="submit">Book and Pay</button>
                </div>
                {/* <span className="btn">Book and Pay</span> */}
            </div>
            <div className="col-12">

            </div>
            <div className="room-calendar__timeslots__please-note col-12 text-center mt-4">
                <p className="text-uppercase text-">Please note - adding to basket will redirect you to the locations page</p>
            </div>
        </form>
    );
}
}

try to do something like this:尝试做这样的事情:

import ReactDOM from 'react-dom';
export default class TimeSlots extends React.Component {
  constructor(props) {
    super(props);
    this.telephone = getCalendarWrapper().dataset.telephone;
    // this.timeSlotButtons = React.createRef();
    // this.monthPrevious = React.createRef();
    // this.monthPreviousByYear = React.createRef();
    // this.monthForward = React.createRef();
    // this.monthForwardByYear = React.createRef();
    this.state = {
      currentDate: this.props.currentDate,
      timesAvailable: this.props.timesAvailable,
      guests: null,
      guestsSelected: null,
      timeSlotSelected: null,
      bookingModal: {
        show: false
      }
    };

    console.log(this.props.roomSlug);
    console.log(this.props.currentDate);
    console.log(this.props.timesAvailable);
  }
  // -----------------
  // -- RENDERS GUEST OPTIONS WHEN USER HAS CLICKED A TIME SLOT
  // -----------------
  renderGuestOptions() {
    // renderGuestOptions(props) {
    // const guestDataTest = props.guestData.guestData;
    const guestData = this.props.guestData;
    console.log(this);

    if (guestData) {
      return (
        // onChange we update the guestSelected state, which will then be used in the ajax request if its added
        <select
          className="form-control"
          onChange={event => console.log(event.target.value)}
        >
          {/* <select className="form-control" onChange={(event) => this.setState({guestsSelected: event.target.value})}> */}
          {Object.keys(guestData).map(function(key) {
            return (
              <option key={key} value={key}>
                {key} People - £{guestData[key]}
              </option>
            );
          })}
        </select>
      );
    } else {
      return <h2>Sorry no times are available</h2>;
    }
  };

  renderGuestPrices() {
    if (!this.state.timeSlotSelected && !this.state.guests) {
      return <div></div>;
    }

    return (
      <form className="timeslot row" onSubmit={this.formSubmitHandler}>
        <div className="col-12 mb-3 text-center">
          <span className="title title--h2">How Many Guests?</span>
        </div>
        <div className="col-12 mb-3 mb-md-4">
          <renderGuestOptions guestData={this.state.guests} />
        </div>
        <div className="col-12 text-center mb-3 mb-md-4">
          <div className="room-calendar__timeslots__help">
            <a href={'tel:' + this.telephone.replace(/ /g, '')}>
              <i className="fa fa-phone"></i> {this.telephone}
            </a>
          </div>
        </div>
        <div className="col-12">
          <div className="d-block px-4">
            <button className="btn d-block w-100 mb-3" type="submit">
              Add To Basket
            </button>
            {/* <span className="btn d-block mb-3" onClick={() => this.addToBasketHandler()}>Add To Basket</span> */}
            <button className="btn d-block w-100" type="submit">
              Book and Pay
            </button>
          </div>
          {/* <span className="btn">Book and Pay</span> */}
        </div>
        <div className="col-12"></div>
        <div className="room-calendar__timeslots__please-note col-12 text-center mt-4">
          <p className="text-uppercase text-">
            Please note - adding to basket will redirect you to the locations
            page
          </p>
        </div>
      </form>
    );
  };

  render() {
    return <renderGuestPrices />;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM