I am relatively new to the React environment and recently created a basic component for a bookmarking feature.
Essentially, when the favourite icon
is clicked,
an ajax call is sent > a record is created in the database > on ajax success, a flash message displays "Page added to favourites."
It's a toggle button, so clicking on it again will,
send another ajax call > delete the record in the database > show a flash message on successful deletion "Page removed from favourites."
Here is the component I wrote, which functions perfectly. However, I am not fond of using the setTimeout
function to hide the flash message. I believe there may be an alternative way (possibly using CSS) to achieve the same result in a more React-oriented manner.
import React, {
PropTypes
} from 'react';
import {
Component
} from 'aplus-base';
import axios from 'axios';
const API = "http://localhost:3000/favourites/toggle"
const API2 = "http://localhost:3000/favourites/current_bookmark_status"
@Component
export default class Bookmark extends React.Component {
static styles = require('./bookmark.sass')
state = {
bookmarked: '',
message: "",
alert: false
}
componentDidMount() {
this.fetchData();
}
toggle() {
const querystring = require('querystring')
axios.post(API, querystring.stringify({
current_page_key: '/marketing'
}), {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
this.setState({
bookmarked: response.data.bookmarked,
alert: true
});
const message = response.data.bookmarked ? "Added to Favourites" : "Removed from Favourites"
this.setState({
message
})
setTimeout(() => {
this.setState({
alert: false
});
}, 2000);
})
}
fetchData = () => {
const querystring = require('querystring')
axios.post(API2, querystring.stringify({
current_page_key: '/marketing'
}), {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
this.setState({
bookmarked: response.data.bookmarked
});
})
}
render() {
return ( <
div >
<
i className = {
this.state.bookmarked ? "icon icon-bookmarked" : "icon icon-bookmark"
}
onClick = {
this.toggle.bind(this)
}
/> <
div styleName = {
`result ${this.state.alert ? "alert-shown": "alert-hidden"}`
} > {
this.state.message
} <
/div> <
/div>
)
}
}
.icon display: inline-block width: 30px height: 30px background: no-repeat center background-size: contain vertical-align: middle &.icon-bookmark background-image: url(../assets/bookmark.png) transition: all 1s linear &.icon-bookmarked background-image: url(../assets/bookmarked.png) transition: all 1s linear .result position: fixed top: 0 left: 40% width: 20% box-sizing: border-box padding: 4px text-align: center font-weight: bold .alert-shown opacity: 1;
transition: all 250ms linear;
.alert-hidden opacity: 0;
transition: all 250ms linear;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>