Skip to content

Commit

Permalink
Implement Redux for State Management.
Browse files Browse the repository at this point in the history
  • Loading branch information
damn-ice committed Jul 6, 2020
1 parent 32e7ea3 commit 1cf570e
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 21 deletions.
52 changes: 52 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"gh-pages": "^3.1.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.0",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"tachyons": "^4.12.0"
},
"scripts": {
Expand Down
17 changes: 17 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
CHANGE_SEARCHFIELD, REQUEST_ROBOTS_PENDING, REQUEST_ROBOTS_SUCCESS, REQUEST_ROBOTS_FAILED
} from "./constants";

export const setSearchField = (text) => ({
type: CHANGE_SEARCHFIELD,
payload: text
})

// We used dispatch here because it's going through thunkMiddleware...
export const requestRobots = () => (dispatch) => {
dispatch({type: REQUEST_ROBOTS_PENDING});
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(data => dispatch({type: REQUEST_ROBOTS_SUCCESS, payload:data }))
.catch(error => dispatch({type: REQUEST_ROBOTS_FAILED, payload: error }))
}
6 changes: 6 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const CHANGE_SEARCHFIELD = "CHANGE_SEARCHFIELD";

export const REQUEST_ROBOTS_PENDING = "REQUEST_ROBOTS_PENDING";
export const REQUEST_ROBOTS_SUCCESS = "REQUEST_ROBOTS_SUCCESS";
export const REQUEST_ROBOTS_FAILED = "REQUEST_ROBOTS_FAILED";

73 changes: 53 additions & 20 deletions src/containers/App.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
import React, {Component} from "react";
import { connect } from "react-redux";
import CardList from "../components/CardList";
// import { robots } from "./robots";
import SearchBox from "../components/SearchBox";
import ErrorBoundary from "../components/ErrorBoundary";
import "./App.css";
import Scroll from "../components/Scroll";
import { setSearchField, requestRobots} from "../actions";


class App extends Component {
constructor () {
super()
this.state = {
robots: [],
searchField: "",
};
// Deals with the state which is gotten from the store...
const mapStateToProps = state => {
return {
// The combiner makes us use state.searchRobots. ..
searchField: state.searchRobots.searchField,
robots: state.requestRobots.robots,
isPending: state.requestRobots.isPending,
error: state.requestRobots.error
}
// Some React specific syntax... => was used so the "this" is for where it was created...
onSearchChange = (event) => {
// Below is how state is changed in react and not this.state.searchField = ...
this.setState({searchField: event.target.value});
}

// Updates the action based on state gotten from store...
const mapDispatchToProps = dispatch => {
return{
onSearchChange: (event) => dispatch(setSearchField(event.target.value)),
// This will pass through thunk... because the action returns a function stead of an object...
onRequestRobots: () => dispatch(requestRobots())
}
}


class App extends Component {

componentDidMount () {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(user => this.setState({robots: user})
);
this.props.onRequestRobots();
}

render () {
const {robots, searchField} = this.state;
// const {robots} = this.state;
const {searchField, onSearchChange, robots, isPending} = this.props;
const filteredRobots = robots.filter(robot => robot.name.toLowerCase()
.includes(searchField.toLowerCase()));
if (robots.length === 0) {
if (isPending) {
return (<h1 className="f1 tc"> Loading...</h1>);
}else {
return (
<div className="tc">
<h1 className="f1">RoboFriends</h1>
<SearchBox search={this.onSearchChange}/>
<SearchBox search={onSearchChange}/>
<Scroll>
<ErrorBoundary>
<CardList robots={filteredRobots}/>
Expand All @@ -52,4 +60,29 @@ class App extends Component {

}

export default App;
export default connect(mapStateToProps, mapDispatchToProps)(App);


// uSInG sTaTe iN rEAcT...,

// constructor () {
// super()
// this.state = {
// robots: [],
// // searchField: "",
// };
// }
// onSearchChange now replaced with redux...
// // Some React specific syntax... => was used so the "this" is for where it was created...
// onSearchChange = (event) => {
// // Below is how state is changed in react and not this.state.searchField = ...
// this.setState({searchField: event.target.value});
// }


// componentDidMount () {
// fetch("https://jsonplaceholder.typicode.com/users")
// .then(response => response.json())
// .then(user => this.setState({robots: user})
// );
// }
13 changes: 12 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from "react-redux";
import { createStore, applyMiddleware, combineReducers} from "redux";
import { createLogger} from "redux-logger";
import thunkMiddleware from "redux-thunk";
import './index.css';
// import App from './App';
// import Hello from './Hello'
import * as serviceWorker from './serviceWorker';
import "tachyons";
import App from './containers/App';
import { searchRobots, requestRobots } from './reducers';

const logger = createLogger();
const rootReducer = combineReducers({searchRobots, requestRobots});
const store = createStore(rootReducer, applyMiddleware(thunkMiddleware,logger));

ReactDOM.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Expand Down
36 changes: 36 additions & 0 deletions src/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
CHANGE_SEARCHFIELD, REQUEST_ROBOTS_PENDING, REQUEST_ROBOTS_SUCCESS, REQUEST_ROBOTS_FAILED
} from "./constants";

const initialStateSearch = {
searchField: ""
}

export const searchRobots = (state=initialStateSearch, action={}) => {
switch(action.type) {
case CHANGE_SEARCHFIELD:
return Object.assign({}, state, {searchField: action.payload});
default:
return state;
}
}

const initialStateRobots = {
isPending: false,
robots: [],
error: ""

}

export const requestRobots = (state=initialStateRobots, action={}) => {
switch (action.type){
case REQUEST_ROBOTS_PENDING:
return Object.assign({}, state, {isPending: true});
case REQUEST_ROBOTS_SUCCESS:
return Object.assign({}, state, {robots: action.payload, isPending: false });
case REQUEST_ROBOTS_FAILED:
return Object.assign({}, state, {error: action.payload, isPending: false });
default:
return state;
}
}

0 comments on commit 1cf570e

Please sign in to comment.