JSFiddle - React, Tailwind, and code Playground

by SupunKavinda

HTML

<div id="app"></div>

CSS

.quote-view {
  padding:15px;
  margin:10px;
  border-radius: 5px;
  background: #3f4046;
  color: #fff;
}

React

class App extends React.Component {

	state = {
		currentPageNumber: 1
	}

	onChange(pageNumber) {
		this.setState({currentPageNumber: pageNumber});
	}

	render() {

		return (
			<div>
				<PageNumberSelector 
					onChange={(val) => this.onChange(val)}
					currentPageNumber={this.state.currentPageNumber}
				/>
				<ProgrammingQuotes currentPageNumber={this.state.currentPageNumber} />
			</div>
		);
	}

}

function PageNumberSelector(props) {

	var options = [1,2,3,4,5].map((i) => {

		return (
			<option
				value={i} 
				key={i}
			>{i}</option>
		);

	});

	return (
		<div>
			Select Page Number: 
			<select 
				value={props.currentPageNumber}
				onChange={(e) => props.onChange(e.target.value)}
			>
				{ options }
			</select>
		</div>
	)
}


class ProgrammingQuotes extends React.Component {

	constructor(props) {
		super(props);
	
		this.state = {
			isLoaded: false,
			error: null,
			quotes: []
		};
	}

	xhr = null;
	isCanceled = false;

	fetchData() {
		// reset
		this.setState({
			isLoaded: false,
			error: null,
			quotes: []
		});

		// abort previous request
		if (this.xhr) {
			this.xhr.abort();
			this.isCanceled = true;
		}

		var xhr = new XMLHttpRequest();

		xhr.addEventListener("readystatechange", () => {
			if (xhr.readyState === 4) {
				if (xhr.status === 200) {
					// request succesful
					var response = xhr.responseText,
						json = JSON.parse(response);
						
					this.setState({
						isLoaded: true,
						quotes: json
					 });          
				} else {

					// this is called when canceled
					if (this.isCanceled)
						return;

					// error
					this.setState({
						isLoaded: true,
						error: xhr.responseText
					});
				}

				this.xhr = null;
				this.isCanceled = false;
			}
		});

		var page = this.props.currentPageNumber;

		xhr.open("GET", "https://programming-quotes-api.herokuapp.com/quotes/page/" + page, true);
		xhr.send();

		this.xhr = xhr;

	}
	
	componentDidMount()...