简体   繁体   中英

Emmitting a React Component value to a Vanilla Javascript

I built a system in vanilla javascript a while back and then when i went to update a certain section of it i decided was gonna try and give it a go in react.

The Basics: I have a function that will initialize a component something this.

function openMediaLibrary(current){
  $('#mediaLibrary').show();
  var container = document.getElementById('mediaLibrary');
  return ReactDOM.render(
    React.createElement(
      MediaLibrary, 
      { url: "/file/getFileList/",current:current }), 
      container
    );
}

The react component is building a media library for the user to select from. Somehow i need to pass back the result to my vanlissa javascript.

Here is the entire react class:

var MediaLibrary = React.createClass({
  getInitialState: function() {
    return {
      data: []
    };
  },

  componentDidMount: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },

  onUpdate: function(val){
    this.setState(val);
  },

  getSelectedFiles: function(){
    var data = _.filter(this.state.data, function(obj) {
      return obj.selected;
    });
    return data;
  },

  render: function() {
    return (
      <div className="media-library panel">
        <FileList data={this.state.data} onUpdate={this.onUpdate}/>
        <FileUpload />
        <SubmitSelected submitSelected={this.getSelectedFiles}/>
      </div>
    );
  }
});

var FileList = React.createClass({
  handleSelect: function(index) {
    this.props.data[index].selected = (this.props.data[index].selected == true) ? false : true;
    this.props.onUpdate(this.props);
  },
  render: function() {
    var fileNodes = this.props.data.map( function(file,index) {
      var bindClick = this.handleSelect.bind(this,index);
      return (
        <File onClick={bindClick} key={index} data={file} />
      );
    },this);

    return (
      <div className="files-list clearfix ">
        {fileNodes}
      </div>
    );
  }
});

var File = React.createClass({
  render: function() {
    var classes = classNames('media-file', {selected: this.props.data.selected});
    return (
      <div className={classes} onClick={this.props.onClick}>
        <div className="media-file-image-wrapper">
          <img src={this.props.data.thumbnail} />
        </div>
        <span className="media-file-name">{this.props.data.fileName}</span>
      </div>
    );
  }
});

var SubmitSelected = React.createClass({
  handleClick: function(){
    this.props.submitSelected();
  },
  render: function() {
    var bindClick = this.handleClick.bind(this);
    return (
      <div className="SubmitSelected">
        <button className="media-library-submit-selected" onClick={bindClick}>Submit</button>
      </div>
    );
  }
});

var FileUpload = React.createClass({
  render: function() {
    return (
      <div className="file-upload-wrapper">

      </div>
    );
  }
});

the submit selected goes through and grabs all of the selected ones and returns it back to that class. but how do i emit it out to my vanilla js?

Or would it be better to have a button outside of the component grab the the value through its props?

IE

var bob = openMediaLibrary(current);
$('submit-button-outside-react').click(function(){
    return bob.getSelectedFiles();
});

here is an example of my initial state from ajax:

[{
    "id": "1",
    "userId": "2",
    "fileName": "GC3_front (3).png",
    "fileMime": "image\/png",
    "fileUrl": "\/file\/christian\/GC3_front%20%283%29.png",
    "thumbnail": "",
    "uploadDate": "2016-03-08 11:06:43"
}, {
    "id": "2",
    "userId": "2",
    "fileName": "knocking-doors (2).jpg",
    "fileMime": "image\/jpeg",
    "fileUrl": "\/file\/christian\/knocking-doors%20%282%29.jpg",
    "thumbnail": "",
    "uploadDate": "2016-03-08 11:10:45"
}, {
    "id": "3",
    "userId": "2",
    "fileName": "fluent_logo_green (1).png",
    "fileMime": "image\/png",
    "fileUrl": "\/file\/christian\/fluent_logo_green%20%281%29.png",
    "thumbnail": "",
    "uploadDate": "2016-03-08 13:01:28"
}, {
    "id": "4",
    "userId": "2",
    "fileName": "infographic.png",
    "fileMime": "image\/png",
    "fileUrl": "\/file\/christian\/infographic.png",
    "thumbnail": "\/file\/christian\/thumbnail\/infographic.png",
    "uploadDate": "2016-03-08 13:03:22"
}, {
    "id": "5",
    "userId": "2",
    "fileName": "GC3_front (4).png",
    "fileMime": "image\/png",
    "fileUrl": "\/file\/christian\/GC3_front%20%284%29.png",
    "thumbnail": "\/file\/christian\/thumbnail\/GC3_front%20%284%29.png",
    "uploadDate": "2016-03-08 13:09:19"
}]

and then an example after i select an item:

[{
    fileMime: "image/png",
    fileName: "infographic.png",
    fileUrl: "/file/christian/infographic.png",
    id: "4",
    selected: true,
    thumbnail: "/file/christian/thumbnail/infographic.png",
    uploadDate: "2016-03-08 13:03:22",
    userId: "2",
}]

I strongly encourage you to familiarise yourself with the concept of one-way data flow which is integral to React.

Basically React is the view layer. And the view layer is where data ends up, not where it starts. A React component may pass data down to its subcomponents, but it should never pass data up to the rest of the application.

Admittedly, an AJAX call buried in componentDidMount() is a common pattern, particularly in online code examples. But it's a simple pattern. Recognise that this limits the use of this data to the component itself (and its subcomponents). As soon as the rest of the application requires access to that data, it's no longer appropriate to fetch that data within your React component.

All of which is to say, I suggest you place the AJAX call within your "vanilla JavaScript" and feed the result to your React component as props.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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