遇到React LinkedStateMixin问题

时间:2015-09-22 13:31:26

标签: javascript reactjs

我正在尝试对ReactJs进行双向绑定并尝试使用LinkedStateMixin。根据从React 0.14开始的React网站,所有插件都被移动到单独的包中:https://facebook.github.io/react/blog/2015/07/03/react-v0.14-beta-1.html所以我通过npm安装了react-addons-linked-state-mixin,但是当我尝试使用它时出现以下错误:

Uncaught TypeError: this.linkState is not a function

我的代码是:

import React, { PropTypes } from 'react';
import TimelineEvent from './TimelineEvent';
import {TimelineEditButton} from './TimelineEvent';
import styles from './Main.css';
import withStyles from '../../../../decorators/withStyles';
import MainView from '../../../MainView';
import SwapBlock from '../../../SwapBlock';
import RoundButton from '../../../RoundButton';
import LightBox from '../../../LightBox';
import Dropzone from 'react-dropzone';
import classnames from 'classnames';
import LinkedStateMixin from 'react-addons-linked-state-mixin';

@withStyles(styles)
class Main extends React.Component {

  render() {

    let session = this.props.session
    let user = this.props.user

    return (
      <MainView>
        <Timeline session={session} user={user} />
      </MainView>
    );
  }

}

class Timeline extends React.Component {

  // Hide all Partials

  constructor() {
      super();
      this.state = {
        eventTitle: '',
        eventPlace: '',
        eventLocation: '',
        eventDescription: ''
      };
      this.state['addEventPartial'] = false;
      this.state.files = [];
  } 

  openPartial(tag) {
    var tags  = {};
    tags[tag] = true;
    this.setState(tags);
    var e = document.getElementById("add-timeline-event");
    if (!!e && e.scrollIntoView) {
       e.scrollIntoView();
   }
  }

  closePartial(tag) {
    var tags  = {};
    tags[tag] = false;
    this.setState(tags);
  }

  openLightbox(tag) {
    var tags  = {};
    tags[tag] = true;
    this.setState(tags);
   }

  closeLightbox(tag) {
    var tags  = {};
    tags[tag] = false;
    this.setState(tags);
  }

  getPartial(tag)
  {
    return this.state[tag];
  }

  getLightbox(tag)
  {
    return this.state[tag];
  }

  onDrop(files) {
    console.log('Received files: ', files);
    this.setState({
      files: files
    });
  }

  render() {

    let session = this.props.session
    let user = this.props.user
    let isAuth = session.isAuth
    let addEvent = {}
    let events = []

    let data = [{
      id: "123",
      key: "1",
      type: "academic",
      time: "2015 - 2016",
      title: " MSc Software Engineering",
      place: "University of Oxford",
      location: "Oxford, United Kingdom",
      description: "Lorem impsum",
      gallery: []
    },{
      id: "234",
      key: "2",
      type: "professional",
      time: "2015 - 2016",
      title: " MSc Software Engineering",
      place: "University of Oxford",
      location: "Oxford, United Kingdom",
      description: "Lorem impsum",
      gallery: [
        {url: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"}
      ]
    },{
      id: "567",
      key: "3",
      type: "misc",
      time: "2015 - 2016",
      title: " MSc Software Engineering",
      place: "University of Oxford",
      location: "Oxford, United Kingdom",
      description: "Lorem impsum",
      gallery: [{
          index: 1,
          url: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"
        }]
      }]

    // Loop through all Timeline Events

    for (var i = 0; i < data.length; i++) {
      let directions;
      let gallery = [];
      if (i % 2 == 0) {
        directions = "direction-r";
      } else {
        directions = "direction-l"
      }
      for (var j = 0; j < data[i].gallery.length; j++) {
        gallery.push(
          <a onClick={this.openLightbox.bind(this, "galleryLightbox")}><img alt={data[i].title} className="TimelineViewGalleryImage" src={data[i].gallery[j].url} /></a>
      )}
      events.push(
        <li>
          <TimelineEvent 
            key = {data[i].id}
            type={data[i].type}
            time = {data[i].time}
            title = {data[i].title}
            place = {data[i].place}
            location = {data[i].location}
            description = {data[i].description}
            direction = {directions}
            session = {session}
            user = {user}>
            {gallery}
            <TimelineEditButton deleteClick={this.openPartial.bind(this, "addEventPartial")}
             editClick={this.openPartial.bind(this, "addEventPartial")}
              session={session} user={user} eventId={data[i].id} />
          </TimelineEvent>
        </li>
      )
    }

    // Add Event to timeline Dialog

    if (isAuth){
      addEvent = (
        <form className="AddEventForm">
          <SwapBlock show={!this.getPartial("addEventPartial")}>
            <div className="AddEventButton">
              <RoundButton onClick={this.openPartial.bind(this, "addEventPartial")} color="green">
                <span className="EventPlus">+</span>
              </RoundButton>
            </div>

          </SwapBlock>

          <SwapBlock show={this.getPartial("addEventPartial")}>
            <div className="TimelineBackdrop"></div>
            <div className="AddTimelineEvent">
              <button className="AddTimelineEventCloseButton" onClick={this.closePartial.bind(this, "addEventPartial")}>
                <i className="fa fa-times"></i>
              </button>
              <h3>Add Event</h3>
              <div className="AddEventTitle TimelineFormField">
                <input value={eventTitle} className="TimelineInput" placeholder="Title" />
              </div>
              <div className="AddEventPlace TimelineFormField">
                <input valueLink={this.linkState('eventPlace')} className="TimelineInput" placeholder="Place" />
              </div>
              <div className="AddEventLocation TimelineFormField">
                <input valueLink={this.linkState('eventLocation')} className="TimelineInput" placeholder="Location" />
              </div>
              <div className="AddEventDescription TimelineFormField">
                <textarea valueLink={this.linkState('eventDescription')} rows="2" className="TimelineInput" placeholder="Description"></textarea>
              </div>
              <StartDateSelect />
              <EndDateSelect />
              <EventTypeSelect />
              <div className="AddEventMedia TimelineFormField">
                <Dropzone className="Dropzone" activeClassName="DropzoneActive" ref="dropzone" multiple={true} disableClick={false} onDrop={this.onDrop.bind(this)}>
                  <div>Try dropping some files here, or click to select files to upload.</div>
                  {this.state.files.length > 0 ? 
                  <div>
                    <div>{this.state.files.map((file) => 
                      <div className="DropzoneUploadedImageContainer">
                        <img className="DropzoneUploadedImage" src={file.preview} />
                        <br className="clear" />
                      </div> )}
                    </div>
                    <p className="DropzoneFileCount">{this.state.files.length} files</p>
                  </div> : null}
                </Dropzone>
                <p className="AddTimelineEventNote">Note: Images only, maximum 4 images and maximum file size is 2 MB</p>
                <button className="SaveEventButton btn btn-primary">Save</button>
                <button onClick={this.closePartial.bind(this, "addEventPartial")} className="SaveEventButton btn btn-default">Cancel</button>
              </div>
            </div>
          </SwapBlock>

          <SwapBlock show={this.getPartial("addEventPartial")}>
            <div className="TimelineSeparator"></div>
          </SwapBlock>
        </form>
      );
    }

    // Render Timeline

    return (
      <div className="Timeline">  
        <LightBox show={this.getLightbox("galleryLightbox")}>
          <button className="TimelineGalleryCloseButton" onClick={this.closeLightbox.bind(this, "galleryLightbox")}>
            <i className="fa fa-times"></i>
          </button>
          <img src="https://d13yacurqjgara.cloudfront.net/users/14268/screenshots/1934662/taptap_1x.png" />
        </LightBox>
        <h3><span className="TimelineHeading">Timeline</span>
          <div className="TimelineNav">
            <button href="#" className="allFilter active">All</button>
            <button href="#" className="professionalFilter">Professional</button>
            <button href="#" className="academicFilter">Academic</button>
            <button href="#" className="miscFilter">Miscellaneous</button>
          </div>
          <br className="clear" />
        </h3>
        <div className="TimelineContainer" id="add-timeline-event">
          {addEvent}
          <ul className="TimelineView">
            {events}
          </ul>
        </div>
      </div>
    );
  }

}

class StartDateSelect extends React.Component {
  render() {
    return(
      <div className="AddEventDescription TimelineFormField">
        <h5 className="EventTypeField EventDateField"><span className="EventTypeLabel">Start Date</span></h5>
        <div className="EventDateContainer">
          <select className="TimelineFormField">
            <option selected disabled>Year:</option>
            <option value="--">--</option>
            <option value="01">2015</option>
            <option value="02">2014</option>
            <option value="03">2013</option>
          </select>
          <select className="TimelineFormField">
            <option selected disabled>Month:</option>
            <option value="--">--</option>
            <option value="January">December</option>
            <option value="February">November</option>
            <option value="March">October</option>
          </select>
          <select className="TimelineFormField">
            <option selected disabled>Day:</option>
            <option value="--">--</option>
            <option value="2014">31</option>
            <option value="2015">30</option>
            <option value="2016">29</option>
          </select>
        </div>
        <br className="clear" />
      </div>
    );
  }
}

class EndDateSelect extends React.Component {

  render() {
    return(
      <div className="AddEventDescription TimelineFormField">
        <h5 className="EventTypeField EventDateField"><span className="EventTypeLabel">End Date</span></h5>
        <div className="EventDateContainer">
          <select className="TimelineFormField">
            <option selected disabled>Year:</option>
            <option value="--">--</option>
            <option value="01">2015</option>
            <option value="02">2014</option>
            <option value="03">2013</option>
          </select>
          <select className="TimelineFormField">
            <option selected disabled>Month:</option>
            <option value="--">--</option>
            <option value="January">December</option>
            <option value="February">November</option>
            <option value="March">October</option>
          </select>
          <select className="TimelineFormField">
            <option selected disabled>Day:</option>
            <option value="--">--</option>
            <option value="2014">31</option>
            <option value="2015">30</option>
            <option value="2016">29</option>
          </select>
        </div>
        <br className="clear" />
      </div>
    );
  }
}

class EventTypeSelect extends React.Component {
  render() {
    return(
      <div className="AddEventDescription TimelineFormField">
        <h5 className="EventTypeField"><span className="EventTypeLabel">Event Type</span>
          <button className="EventTypeFieldProfessional"><span className="TypeDot"></span>Professional</button>
          <button className="EventTypeFieldAcademic"><span className="TypeDot"></span>Academic</button>
          <button className="EventTypeFieldMiscellaneous"><span className="TypeDot"></span>Miscellaneous</button>
        </h5>
      </div>
    );
  }
}

export default Main;

我不确定我做错了什么。

有什么想法吗?

由于

0 个答案:

没有答案