Javascript React-LinkedStateMixin存在问题

Javascript React-LinkedStateMixin存在问题,javascript,reactjs,Javascript,Reactjs,我尝试在ReactJs上进行双向绑定,并尝试使用LinkedStateMixin。根据React网站,从React 0.14开始,所有插件都已移动到单独的软件包中:因此,我通过npm安装了React插件链接状态mixin,但在尝试使用它时出现以下错误: Uncaught TypeError: this.linkState is not a function 我的代码是: import React, { PropTypes } from 'react'; import TimelineEvent

我尝试在ReactJs上进行双向绑定,并尝试使用LinkedStateMixin。根据React网站,从React 0.14开始,所有插件都已移动到单独的软件包中:因此,我通过npm安装了React插件链接状态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;
import React,{PropTypes}来自'React';
从“/TimelineEvent”导入TimelineEvent;
从“/TimelineEvent”导入{TimelineEditButton};
从“/Main.css”导入样式;
从“../../../../../decorators/withStyles”导入withStyles;
从“../../../MainView”导入MainView;
从“../../../SwapBlock”导入SwapBlock;
从“../../../RoundButton”导入RoundButton;
从“../../../LightBox”导入LightBox;
从“react Dropzone”导入Dropzone;
从“类名称”导入类名称;
从“react addons linked state mixin”导入LinkedStateMixin;
@样式(样式)
类Main扩展了React.Component{
render(){
让session=this.props.session
让user=this.props.user
返回(
);
}
}
类。组件{
//隐藏所有部分
构造函数(){
超级();
此.state={
eventTitle:“”,
事件地点:“”,
事件位置:“”,
事件描述:“”
};
此.state['addEventPartial']=false;
this.state.files=[];
} 
openPartial(标记){
var标签={};
tags[tag]=true;
此设置状态(标签);
var e=document.getElementById(“添加时间线事件”);
如果(!!e&&e.scrollIntoView){
e、 scrollIntoView();
}
}
关闭部分(标记){
var标签={};
tags[tag]=false;
此设置状态(标签);
}
openLightbox(标签){
var标签={};
tags[tag]=true;
此设置状态(标签);
}
封闭灯箱(标签){
var标签={};
tags[tag]=false;
此设置状态(标签);
}
getPartial(标记)
{
返回此.state[tag];
}
getLightbox(标签)
{
返回此.state[tag];
}
onDrop(文件){
log('Received files:',files);
这是我的国家({
文件:文件
});
}
render(){
让session=this.props.session
让user=this.props.user
让isAuth=session.isAuth
设addEvent={}
让事件=[]
让数据=[{
身份证号码:“123”,
关键:“1”,
类型:“学术”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[]
},{
id:“234”,
键:“2”,
类型:“专业”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[
{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"}
]
},{
身份证号码:“567”,
关键:“3”,
类型:“杂项”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[{
索引: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"
}]
}]
//循环浏览所有时间轴事件
对于(变量i=0;i
{画廊}

)
}
//“将事件添加到时间轴”对话框
if(isAuth){
addEvent=(
+
添加事件
尝试在此处删除一些文件,或单击以选择要上载的文件。
{this.state.files.length>0?
{this.state.files.map((文件)=>

)}

{this.state.files.length}文件

:null}

注意:仅图像,最多4个图像,最大文件大小为2MB

拯救 取消 ); } //渲染时间轴 返回( 时间线 全部的 专业的 学术的 混杂的
{addEvent}
    {events}
); } } 类StartDateSelect扩展了React.Component{ render(){ 返回( 开始日期 年份: -- 2015 20
class Something extends React.Component {
    state = {
        email: ''
    }

    emailValueLink = (value) => {
        return {
            value: this.state.email,
            requestChange: this.handleEmailChange
        };
    }

    handleEmailChange(newEmail) {
        this.setState({email: newEmail});
    }

    render() {
        <input type="email" valueLink={this.emailValueLink()} />
    }
}