Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building with React.js & Flux

koba04
April 28, 2015

Building with React.js & Flux

Building Apps with React.js & Flux

第56回 HTML5とか勉強会(JavaScriptフレームワーク最前線 - AngularJS、React.js - )

https://html5j.doorkeeper.jp/events/23074

koba04

April 28, 2015
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. )FMMP import React from ‘react’; class Hello extends React.Component {

    render() { return <div>Hello {this.props.name}</div>; } } React.render( <Hello name=“World” />, document.getElementById(‘app’) ); // <div>Hello World</div>
  2. )FMMP import React from ‘react’; class Hello extends React.Component {

    render() { return <div>Hello {this.props.name}</div>; } } React.render( <Hello name=“World” />, document.getElementById(‘app’) ); // <div>Hello World</div> ʂʂʂʁʁʁ
  3. 1SPQ4UBUF w 1SPQ w $PNQPOFOUͷ*OUFSGBDF w *NNVUBCMF w 4UBUF w

    $PNQPOFOU͕0XOFSTIJQΛ࣋ͭ஋ w ࢠʹ1SPQͱͯ͠౉͢
  4. class App extends React.Component { constructor(props) { super(props); this.state =

    { stories: [], filterText: ‘’}; } static get propTypes() { return { count: React.PropTypes.number } } static getDefaultProps() { return { count: 50 } } handleFilter(input) {} render() { return ( <div> <h1>HackerNews Stories</h1> <InputFilter handleFilter={this.handleFilter.bind(this)} /> <HNStories stories={this.state.stories} /> </div> ); } } QBTTBTQSPQT IBTBTUBUF SFDFJWFQSPQT
  5. class InputFilter extends React.Component { static get propTypes() { return

    { handleFilter: React.PropTypes.func.isRequired } } onInput(e) { this.props.handleFilter(e.target.value); } render() { return ( <div> <input type="text" placeholder="filter" onChange={this.onInput.bind(this)} /> </div> ) } } MJTUFOUIFDIBOHFFWFOU EFMFHBUFUIFFWFOU
  6. class HNStories extends React.Component { static get propTypes() { return

    { stories: React.PropTypes.arrayOf(React.PropTypes.object).isRequired } } render() { return ( <div> {this.props.stories.map( story => <HNStory key={story.id} story={story} /> )} </div> ); } } QBTTBTQSPQT
  7. class HNStory extends React.Component { static get propTypes() { return

    { story: React.PropTypes.object.isRequired } } render() { const {rank, url, title, by, kids} = this.props.story; const commentCount = kids ? kids.length : 0; return ( <div> <div>{rank}</div> <div> {title} </div> <div> <span>by {by}</span> <span>{commentCount}comments</span> <span><a href={url} target="_blank">link</a></span> </div> </div> ); } }
  8. class App extends React.Component { : componentDidMount() { fetch(HN_TOP_STORY_URL) .then(res

    => res.json()) .then(ids => { ids.slice(0, this.props.count).forEach((id, index) => { fetch(`${HN_STORY_URL}/${id}.json`) .then(res => res.json()) .then(story => { story.rank = index + 1; this.setState({ stories: this.state.stories.concat([story]).sort((a,b) => a.rank - b.rank) }); }) }) }); } }
  9. class App extends React.Component { : handleFilter(input) { this.setState({filterText: input});

    } filterStories() { const filterText = this.state.filterText.toLowerCase(); return this.state.stories.filter(story => { return !filterText || story.title.toLowerCase().indexOf(filterText) !== -1 || story.by.toLowerCase().indexOf(filterText) !== -1 ; }); } render() { return ( <div style={style.root}> <h1>HackerNews Stories</h1> <InputFilter handleFilter={this.handleFilter.bind(this)} /> <HNStories stories={this.filterStories()} /> </div> ); } }
  10. class InputFilter extends React.Component { static get propTypes() { return

    { handleFilter: React.PropTypes.func.isRequired } } onInput(e) { this.props.handleFilter(e.target.value); } render() { return ( <div> <input type="text" placeholder="filter" onChange={this.onInput.bind(this)} /> </div> ) } }
  11. class App extends React.Component { constructor(props) { super(props); this.state =

    {stories: HNStoriesStore.filteredStrories()}; this._onChange = this._onChange.bind(this); } static get propTypes() { return { count: React.PropTypes.number}} static getDefaultProps() { return {count: 50} } componentDidMount() { HNStoriesStore.addChangeListener(this._onChange); AppHNStoriesActionCreators.fetch(this.props.count); } componentWillUnmount() { HNStoriesStore.removeChangeListener(this._onChange); } _onChange() { this.setState({ stories: HNStoriesStore.filteredStrories()}); } render() { return ( <div> <h1>HackerNews Stories</h1> <InputFilter /> <HNStories stories={this.state.stories} /> </div> ) } } "DUJPO$SFBUPSΛݺͿ
  12. class InputFilter extends React.Component { onInput(e) { AppHNStoriesActionCreators.filter(e.target.value); } render()

    { return ( <div> <input type="text" placeholder="title" onChange={this.onInput.bind(this)} /> </div> ) } } "DUJPO$SFBUPSΛݺͿ
  13. const Action = { fetch(count) { fetch(HN_TOP_STORY_URL) .then(res => res.json())

    .then(ids => { ids.slice(0, count).forEach((id, index) => { fetch(`${HN_STORY_URL}/${id}.json`) .then(res => res.json()) .then(story => { story.rank = index + 1; AppDispatcher.dispatch({ type: ActionTypes.RECEIVE_STORY, story: story }); }) }) }); }, filter(text) { AppDispatcher.dispatch({ type: ActionTypes.RECEIVE_FILTER_TEXT, text: text }); } }; "DUJPOΛൃߦͯ͠ %JTQBUDIFS΁
  14. const HNStories = assign({}, EventEmitter.prototype, { : }); HNStories.dispatchToken =

    AppDispatcher.register(action => { switch (action.type) { case ActionTypes.RECEIVE_STORY: stories = stories.concat([action.story]); HNStories.emitChange(); break; case ActionTypes.RECEIVE_FILTER_TEXT: filterText = action.text.toLowerCase(); HNStories.emitChange(); break; } }); શͯͷ"DUJPOΛड͚ͯ ඞཁͳ΋ͷ͚ͩॲཧ͢Δ
  15. let stories = []; let filterText = ''; const HNStories

    = assign({}, EventEmitter.prototype, { emitChange() { this.emit(CHANGE_EVENT); }, addChangeListener(callback) { this.on(CHANGE_EVENT, callback); }, removeChangeListener(callback) { this.removeListener(CHANGE_EVENT, callback); }, filteredStrories() { return stories.filter(story => { return !filterText || story.title.toLowerCase().indexOf(filterText) !== -1 || story.by.toLowerCase().indexOf(filterText) !== -1 ; }); } }); : : $PNQPOFOUʹର͢Δ &WFOUͱHFUUFS
  16. class App extends React.Component { constructor(props) { super(props); this.state =

    {stories: HNStoriesStore.filteredStrories()}; this._onChange = this._onChange.bind(this); } static get propTypes() { return { count: React.PropTypes.number}} static getDefaultProps() { return {count: 50} } componentDidMount() { HNStoriesStore.addChangeListener(this._onChange); AppHNStoriesActionCreators.fetch(this.props.count); } componentWillUnmount() { HNStoriesStore.removeChangeListener(this._onChange); } _onChange() { this.setState({ stories: HNStoriesStore.filteredStrories()}); } render() { return ( <div> <h1>HackerNews Stories</h1> <InputFilter /> <HNStories stories={this.state.stories} /> </div> ) } } 4UPSF͔ΒσʔλΛड͚औΓ &WFOUΛड͚ͯߋ৽