|
// pages/tags.js |
|
// At 127.0.0.1:3000/tags on a next dev run |
|
import React from "react"; |
|
|
|
function appendTag(tags, newTag) { |
|
// Since arrays are mutable, we use `concat` to return a copy of the original |
|
// array with our new tag |
|
// Question: is the reason to not just change it mutably that that isn't clean |
|
// and against the ethos of React? |
|
|
|
// NOTE: We're now using Set to guarantee uniqueness |
|
// Question: why do we need to transform it back into an array for this to work? |
|
var newtags = [].concat(tags, newTag); |
|
var uniqtags = new Set(newtags); |
|
// I'm assuming we can do something more interesting than alphabetical sort later on |
|
return [...uniqtags].sort() |
|
} |
|
|
|
// Heavily based on the template provided in |
|
// https://facebook.github.io/react/docs/forms.html#controlled-components |
|
class TagForm extends React.Component{ |
|
constructor(props){ |
|
super(props); |
|
this.state = {value: ""}; |
|
this.handleChange = this.handleChange.bind(this) |
|
this.handleChange = this.handleChange.bind(this) |
|
|
|
} |
|
|
|
handleChange(event){ |
|
this.setState({value: event.target.value}); |
|
} |
|
|
|
handleSubmit(event){ |
|
event.preventDefault(); |
|
this.props.onChange(appendTag(this.props.tags, this.state.value )); |
|
} |
|
|
|
render() { |
|
return ( |
|
// Q: if you uncomment line 42, this will work; why doesn't line 43? |
|
// <form onSubmit={(e) => {this.handleSubmit(e); e.preventDefault();}}> |
|
<form onSubmit={this.handleSubmit}> |
|
<label> |
|
Tag: |
|
<input type="text" value={this.state.value} onChange={this.handleChange}/> |
|
</label> |
|
</form> |
|
); |
|
} |
|
} |
|
// Filled this in with my real implementation (mostly above in TagForm) |
|
const Tags = props => ( |
|
<div> |
|
{/* |
|
Question: I need to pass this down to TagForm in order for it to bubble up |
|
correctly. Is there a more idiomatic way to approach this? */} |
|
<TagForm tags={props.tags} onChange={props.onChange}/> |
|
<ul>{props.tags.map(tag => <li key={tag}>{tag}</li>)}</ul> |
|
</div> |
|
); |
|
|
|
export default class TagPage extends React.Component { |
|
tagUpdate = tags => this.setState({ tags }); |
|
|
|
constructor(props) { |
|
super(props); |
|
this.state = { |
|
tags: ["test"] |
|
}; |
|
} |
|
|
|
render() { |
|
return <Tags tags={this.state.tags} onChange={this.tagUpdate} />; |
|
} |
|
} |