Skip to content

Instantly share code, notes, and snippets.

@ddunlop
Created December 23, 2016 16:09
Show Gist options
  • Save ddunlop/0c7b4b2660065e55a98b4aa8db56f125 to your computer and use it in GitHub Desktop.
Save ddunlop/0c7b4b2660065e55a98b4aa8db56f125 to your computer and use it in GitHub Desktop.
import React from 'react';
import classnames from 'classnames';
/*
This would be a page level component. It handles loading all data.
a) The orphan data is triggered by componentWillMount which is part of the React component
life cycle called once as the component loads
b) video search data is loaded when there is a new search preformed 1) When an orphan is
selected, including selecting the first orphan when the data is first loaded 2) When the
search form is submitted when the user wants to do a custom search
*/
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {
orphans: [],
orphansLoading: false,
selectedOrphan: null,
search: null,
searchLoading: false,
videos: [],
};
}
componentWillMount() {
this.setState({ orphansLoading: true })
// This should be the fetch that gets the orphans
setTimeout(() => {
let orphans = [ 'one', 'two', 'three' ];
this.setState({
orphans,
orphansLoading: false
});
this.selectOrphan(0);
}, 500);
}
selectOrphan(id) {
this.setState({ selectedOrphan: id });
this.setSearch(this.state.orphans[id]);
}
setSearch(search) {
this.setState({
search,
searchLoading: true,
});
// This should become a fetch() that does the search
setTimeout(() => {
this.setState({
videos: ['cat', 'dog' ],
searchLoading: false,
});
}, 200);
}
render() {
let {
orphans,
orphansLoading,
selectedOrphan,
search,
searchLoading,
videos
} = this.state;
return (
<div className="clearFix">
<Loading loading={orphansLoading}>
<div className="col xs-col-6">
<ul>
{orphans.map((orphan, i) => {
let className = classnames({
'fill-green': i === selectedOrphan,
});
return (
<li className={className} onClick={() => this.selectOrphan(i)} key={i}>
{orphan}
</li>
)
})}
</ul>
</div>
<VideoArea
search={search}
loading={searchLoading}
videos={videos}
action={(query) => this.setSearch(query)}
/>
</Loading>
</div>
);
}
}
/*
This poorly named component is showing two things
1) The action prop is used to pass information to the parent that a search should be
preformed
2) The search prop is used to set the search state initially and on prop change but the
state can be changed locally. This is so that the parent can pass in a new value when
an orphan is selected but also the search input box can be manipulated
*/
class VideoArea extends React.Component {
constructor(props) {
super(props);
this.state = {
search: props.search || '',
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.search === this.props.search) { return; }
this.setState({ search: nextProps.search });
}
handleSubmit(e) {
e.preventDefault();
this.props.action(this.state.search);
}
onInputChange(event) {
let search = event.target.value;
this.setState({ search: search });
}
render() {
let { loading, videos } = this.props;
let { search } = this.state;
return (
<div className="col xs-col-6">
<h2>videos</h2>
<form onSubmit={(event) => this.handleSubmit(event)}>
<input
type="text"
className="text-input"
value={search}
placeholder="Search Here!"
onChange={(event) => this.onInputChange(event)}
/>
</form>
<Loading loading={loading}>
<ul>
{videos.map(video => <li key={video}>{video}</li>)}
</ul>
</Loading>
</div>
);
}
}
/*
This is a quick component to show loading state
*/
let Loading = ({ loading, children }) => {
if (loading) {
return <h2>Loading...</h2>
}
return (
<div>{children}</div>
);
};
export default Page;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment