File tree Expand file tree Collapse file tree 10 files changed +138
-20
lines changed Expand file tree Collapse file tree 10 files changed +138
-20
lines changed Original file line number Diff line number Diff line change 88 "react-redux" : " ^5.0.5" ,
99 "react-scripts" : " 1.0.10" ,
1010 "redux" : " ^3.7.2" ,
11- "redux-logger" : " ^3.0.6"
11+ "redux-logger" : " ^3.0.6" ,
12+ "redux-saga" : " ^0.15.6"
1213 },
1314 "scripts" : {
1415 "start" : " react-scripts start" ,
Original file line number Diff line number Diff line change 1+ import {
2+ STORIES_ADD ,
3+ STORIES_FETCH ,
4+ } from '../constants/actionTypes' ;
5+
6+ const doAddStories = stories => ( {
7+ type : STORIES_ADD ,
8+ stories,
9+ } ) ;
10+
11+ const doFetchStories = query => ( {
12+ type : STORIES_FETCH ,
13+ query,
14+ } ) ;
15+
16+ export {
17+ doAddStories ,
18+ doFetchStories ,
19+ } ;
Original file line number Diff line number Diff line change @@ -2,9 +2,13 @@ import React from 'react';
22import './App.css' ;
33
44import Stories from './Stories' ;
5+ import SearchStories from './SearchStories' ;
56
67const App = ( ) =>
78 < div className = "app" >
9+ < div className = "interactions" >
10+ < SearchStories />
11+ </ div >
812 < Stories />
913 </ div >
1014
Original file line number Diff line number Diff line change 1+ import React , { Component } from 'react' ;
2+ import { connect } from 'react-redux' ;
3+ import { doFetchStories } from '../actions/story' ;
4+ import Button from './Button' ;
5+
6+ const applyQueryState = query => ( ) => ( {
7+ query
8+ } ) ;
9+
10+ class SearchStories extends Component {
11+ constructor ( props ) {
12+ super ( props ) ;
13+
14+ this . state = {
15+ query : '' ,
16+ } ;
17+
18+ this . onChange = this . onChange . bind ( this ) ;
19+ this . onSubmit = this . onSubmit . bind ( this ) ;
20+ }
21+
22+ onSubmit ( event ) {
23+ const { query } = this . state ;
24+ if ( query ) {
25+ this . props . onFetchStories ( query )
26+
27+ this . setState ( applyQueryState ( '' ) ) ;
28+ }
29+
30+ event . preventDefault ( ) ;
31+ }
32+
33+ onChange ( event ) {
34+ const { value } = event . target ;
35+ this . setState ( applyQueryState ( value ) ) ;
36+ }
37+
38+ render ( ) {
39+ return (
40+ < form onSubmit = { this . onSubmit } >
41+ < input
42+ type = "text"
43+ value = { this . state . query }
44+ onChange = { this . onChange }
45+ />
46+ < Button type = "submit" >
47+ Search
48+ </ Button >
49+ </ form >
50+ ) ;
51+ }
52+ }
53+
54+ const mapDispatchToProps = ( dispatch ) => ( {
55+ onFetchStories : query => dispatch ( doFetchStories ( query ) ) ,
56+ } ) ;
57+
58+ export default connect (
59+ null ,
60+ mapDispatchToProps
61+ ) ( SearchStories ) ;
Original file line number Diff line number Diff line change 1- export const STORY_ARCHIVE = 'STORY_ARCHIVE' ;
1+ export const STORY_ARCHIVE = 'STORY_ARCHIVE' ;
2+ export const STORIES_FETCH = 'STORIES_FETCH' ;
3+ export const STORIES_ADD = 'STORIES_ADD' ;
Original file line number Diff line number Diff line change 1- const INITIAL_STATE = [
2- {
3- title : 'React' ,
4- url : 'https://facebook.github.io/react/' ,
5- author : 'Jordan Walke' ,
6- num_comments : 3 ,
7- points : 4 ,
8- objectID : 0 ,
9- } , {
10- title : 'Redux' ,
11- url : 'https://github.com/reactjs/redux' ,
12- author : 'Dan Abramov, Andrew Clark' ,
13- num_comments : 2 ,
14- points : 5 ,
15- objectID : 1 ,
16- } ,
17- ] ;
1+ import { STORIES_ADD } from '../constants/actionTypes' ;
2+
3+ const INITIAL_STATE = [ ] ;
4+
5+ const applyAddStories = ( state , action ) =>
6+ action . stories ;
187
198function storyReducer ( state = INITIAL_STATE , action ) {
209 switch ( action . type ) {
10+ case STORIES_ADD : {
11+ return applyAddStories ( state , action ) ;
12+ }
2113 default : return state ;
2214 }
2315}
Original file line number Diff line number Diff line change 1+ import { takeEvery , all } from 'redux-saga/effects' ;
2+ import { STORIES_FETCH } from '../constants/actionTypes' ;
3+ import { handleFetchStories } from './story' ;
4+
5+ function * watchAll ( ) {
6+ yield all ( [
7+ takeEvery ( STORIES_FETCH , handleFetchStories ) ,
8+ ] )
9+ }
10+
11+ export default watchAll ;
Original file line number Diff line number Diff line change 1+ import { call , put } from 'redux-saga/effects' ;
2+ import { doAddStories } from '../actions/story' ;
3+
4+ const HN_BASE_URL = 'http://hn.algolia.com/api/v1/search?query=' ;
5+
6+ const fetchStories = query =>
7+ fetch ( HN_BASE_URL + query )
8+ . then ( response => response . json ( ) ) ;
9+
10+ function * handleFetchStories ( action ) {
11+ const { query } = action ;
12+ const result = yield call ( fetchStories , query ) ;
13+ yield put ( doAddStories ( result . hits ) ) ;
14+ }
15+
16+ export {
17+ handleFetchStories ,
18+ } ;
Original file line number Diff line number Diff line change 11import { createStore , applyMiddleware } from 'redux' ;
22import { createLogger } from 'redux-logger' ;
3+ import createSagaMiddleware from 'redux-saga' ;
34import rootReducer from '../reducers' ;
5+ import rootSaga from '../sagas' ;
46
57const logger = createLogger ( ) ;
8+ const saga = createSagaMiddleware ( ) ;
69
710const store = createStore (
811 rootReducer ,
912 undefined ,
10- applyMiddleware ( logger )
13+ applyMiddleware ( saga , logger )
1114) ;
1215
16+ saga . run ( rootSaga ) ;
17+
1318export default store ;
You can’t perform that action at this time.
0 commit comments