Skip to content

Latest commit

 

History

History
173 lines (133 loc) · 5.25 KB

6-integrate-with-third-party-apis.md

File metadata and controls

173 lines (133 loc) · 5.25 KB

Integrate a third-party library

Here we are going to use the modal component from materialize css to add comments on a wine

The Wine API

For this step you'll need to add comments to the API exposed at https://wines-api.herokuapp.com.

The URL you need are the following

  • POST https://wines-api.herokuapp.com/api/wines/:id/comments => add a comment on the wine

Obviously, you'll need to add the following functions to the module responsible for calling the API

export function commentWine(id, content) {
  return fetch(`${host}/api/wines/${id}/comments`, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ title: 'The title', content })
  });
}

The <CommentButton /> component

the comment button is a very simple component, its only job is to trigger the <CommentModal /> component opening through a function call

The contract of <CommentButton /> is the following

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export class CommentButton extends Component {
  static propTypes = {
    openCommentModal: PropTypes.func
  };
  ...
}

the view of <CommentButton /> component will look something like

<a class="waves-effect waves-teal btn-flat">
  Comment <i class="material-icons left">comment</i>
</a>

The <CommentModal /> component

The <CommentModal /> component is a modal from materialize css. This component will have an input text for the comment content and some buttons to validate or cancel the comment.

The only issue is that the materialize css modal component is using jQuery to work. So we will need to use some special feature of React to deal with that.

The contract of <CommentModal /> is the following

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export class CommentModal extends Component {

  static propTypes = {
    isOpen: PropTypes.bool
  };

  state = {
    comment: ''
  };

  componentDidMount() {
    // if this.props.isOpen then open the modal on mount
  }

  componentWillUnmount() {
    // close the modal
  }

  componentWillReceiveProps(nextProps) {
    // if nextProps.isOpen !== this.props.isOpen, open or close modal according to the new value
  }
  ...
});

the view of <CommentModal /> component will look something like

<div class="modal">
  <div class="modal-content">
    <h4>Tell us something about this wine</h4>
    <form class="col s12">
      <div class="row">
        <div class="input-field col s12">
          <input id="inputComment" type="text" class="validate"/>
          <label htmlFor="inputComment">Your comment</label>
        </div>
      </div>
    </form>
  </div>
  <div class="modal-footer">
    <a href="#!" class="modal-action waves-effect waves-green btn-flat">Submit</a>
    <a href="#!" class="modal-action waves-effect waves-green btn-flat">Cancel</a>
  </div>
</div>

Integration with Materialize CSS modal component

According to the documentation of materialize css modal component to open or close a modal you need to do the following code

window.$(theDomNodeOfTheModal).openModal(); // open the modal
window.$(theDomNodeOfTheModal).closeModal(); // close the modal

to use this code inside a our React component, we need to get a reference to the actual DOM node generated by React (the one with the modal class). To do that we are going to use React refs

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export class CommentModal extends Component {
  ...
  render() {
    // here we set the value of this.modalNode to the actual ref to the DOM node
    //                                        ||||
    //                            vvvvvvvvvvvvvvvvvvvvvvvvvvv
    return (
      <div className="modal" ref={ref => this.modalNode = ref}>
        <div className="modal-content">
          <h4>Tell us something about this wine</h4>
          <form className="col s12">
            <div className="row">
              <div className="input-field col s12">
                <input id="inputComment" type="text" className="validate"/>
                <label htmlFor="inputComment">Your comment</label>
              </div>
            </div>
          </form>
        </div>
        <div className="modal-footer">
          <a href="#!" className="modal-action waves-effect waves-green btn-flat">Submit</a>
          <a href="#!" className="modal-action waves-effect waves-green btn-flat">Cancel</a>
        </div>
      </div>
    );
  }
}

using the ref trick, you can now access this.modalNode inside your code, so you can use code like

window.$(this.modalNode).openModal(); // open the modal
window.$(this.modalNode).closeModal(); // close the modal

What it should look like

And now your wine details component should look something like that

Add comment

What's next

react-101 is now over. See you soon for react-102 ;-)