Connecting Redux to the Application
https://frontendmasters.com/courses/intermediate-react-v2/connecting-redux-to-the-application/
Uptade App.js
--- a/src/App.js
+++ b/src/App.js
@@ -1,14 +1,14 @@
// don't need useState since it's a Redux "replacement"
-import React, { useState } from "react";
+import React from "react";
import ReactDOM from "react-dom";
import { Router, Link } from "@reach/router";
+ // this will provide the Redux store to the entire application
+import { Provider } from "react-redux";
+ // need the store as well
+import store from "./store";
import Details from "./Details";
import SearchParams from "./SearchParams";
-import ThemeContext from "./ThemeContext";
const App = () => {
- const theme = useState("darkblue");
return (
- <ThemeContext.Provider value={theme}>
// add the provider
// and now Redux is available to the entire App
+ <Provider store={store}>
<div>
<header>
<Link to="/">Adopt Me!</Link>
@@ -19,7 +19,7 @@ const App = () => {
<Details path="/details/:id" />
</Router>
</div>
- </ThemeContext.Provider>
+ </Provider>
);
};
update SearchParams
import React, { useState, useEffect, useContext } from "react";
import pet, { ANIMALS } from "@frontendmasters/pet";
// **** 1. import connect. ↴
import { connect } from "react-redux";
import useDropdown from "./useDropdown";
import Results from "./Results";
import changeLocation from "./actionCreator/changeLocation";
import changeTheme from "./actionCreator/changeTheme";
// **** 4. provide the props here. ↴
const SearchParams = props => ({ theme, location, setTheme, updateLocation }) => {
// **** 2. can delete the context refences. ↴
//- const [theme setTheme] = useContext(ThemeContext)
const [breeds, updateBreeds] = useState([]);
const [pets, setPets] = useState([]);
const [animal, AnimalDropdown] = useDropdown("Animal", "dog", ANIMALS);
const [breed, BreedDropdown, updateBreed] = useDropdown("Breed", "", breeds);
async function requestPets() {
const { animals } = await pet.animals({
// **** 3. update location. ↴
location: props.location,
breed,
type: animal
});
setPets(animals || []);
}
useEffect(() => {
updateBreeds([]);
updateBreed("");
pet.breeds(animal).then(({ breeds }) => {
const breedStrings = breeds.map(({ name }) => name);
updateBreeds(breedStrings);
}, console.error);
}, [animal]);
return (
<div className="search-params">
<form
onSubmit={e => {
e.preventDefault();
requestPets();
}}
>
<label htmlFor="location">
Location
<input
id="location"
// **** 5. update props.location here. ↴
value={props.location}
placeholder="Location"
// **** 6. use again props here. ↴
onChange={e => props.updateLocation(e.target.value)}
/>
</label>
<AnimalDropdown />
<BreedDropdown />
<label htmlFor="location">
Theme
<select
// **** 7 again change to props.theme. ↴
value={props.theme}
// **** 8 and setTheme to props.setTheme. ↴
onChange={e => props.setTheme(e.target.value)}
onBlur={e => props.setTheme(e.target.value)}
>
<option value="peru">Peru</option>
<option value="darkblue">Dark Blue</option>
<option value="chartreuse">Chartreuse</option>
<option value="mediumorchid">Medium Orchid</option>
</select>
</label>
<button style={{ backgroundColor: props.theme }}>Submit</button>
</form>
<Results pets={pets} />
</div>
);
};
// **** 9. start integrating Redux here. ↴
// this will extract state from Redux
// and pass to the component
const mapStateToProps = ({ theme, location }) => ({
theme,
location
});
// **** 10. add the dispatch. ↴
// so that we can send updates to Redux
const mapDispatchToProps = dispatch => ({
// in the workshop it's called updateLocation...
setLocation(location) {
// changeLocation is from the actionCreators ↴
dispatch(changeLocation(location));
},
setTheme(theme) {
dispatch(changeTheme(theme));
}
});
// **** 11. use the connect. ↴
// it's a bit strange pattern, to call a function
// that returns a function
// its because you will be able to use
// connect as a decorator later
export default connect(
mapStateToProps,
mapDispatchToProps
)(SearchParams);
Now, the Location state is no longer held by the the SearchParams component, but lives in redux.