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 8
8
"react-redux" : " ^5.0.5" ,
9
9
"react-scripts" : " 1.0.10" ,
10
10
"redux" : " ^3.7.2" ,
11
- "redux-logger" : " ^3.0.6"
11
+ "redux-logger" : " ^3.0.6" ,
12
+ "redux-saga" : " ^0.15.6"
12
13
},
13
14
"scripts" : {
14
15
"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';
2
2
import './App.css' ;
3
3
4
4
import Stories from './Stories' ;
5
+ import SearchStories from './SearchStories' ;
5
6
6
7
const App = ( ) =>
7
8
< div className = "app" >
9
+ < div className = "interactions" >
10
+ < SearchStories />
11
+ </ div >
8
12
< Stories />
9
13
</ div >
10
14
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 ;
18
7
19
8
function storyReducer ( state = INITIAL_STATE , action ) {
20
9
switch ( action . type ) {
10
+ case STORIES_ADD : {
11
+ return applyAddStories ( state , action ) ;
12
+ }
21
13
default : return state ;
22
14
}
23
15
}
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 1
1
import { createStore , applyMiddleware } from 'redux' ;
2
2
import { createLogger } from 'redux-logger' ;
3
+ import createSagaMiddleware from 'redux-saga' ;
3
4
import rootReducer from '../reducers' ;
5
+ import rootSaga from '../sagas' ;
4
6
5
7
const logger = createLogger ( ) ;
8
+ const saga = createSagaMiddleware ( ) ;
6
9
7
10
const store = createStore (
8
11
rootReducer ,
9
12
undefined ,
10
- applyMiddleware ( logger )
13
+ applyMiddleware ( saga , logger )
11
14
) ;
12
15
16
+ saga . run ( rootSaga ) ;
17
+
13
18
export default store ;
You can’t perform that action at this time.
0 commit comments