Так что для вашего store.js
вместо:
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
попытайтесь:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk';
import App from "./components/App";
import reducers from "./reducers";
const store = createStore(reducers, applyMiddleware(thunk));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.querySelector("#root")
);
Затем в вашем файле App.js
вместо:
import React, { Component } from "react";
import { Provider } from "react-redux";
import store from "./store";
import SearchBar from "./components/SearchBar";
import ImageList from "./components/ImageList";
import "./app.scss";
class App extends Component {
render() {
return (
<Provider store={store}>
<SearchBar onSubmit={this.onSearchSubmit} />
<div>
<ImageList images={this.state.images} />
</div>
</Provider>
);
}
}
export default App;
try:
import React, { Component } from "react";
import SearchBar from "./components/SearchBar";
import ImageList from "./components/ImageList";
import "./app.scss";
class App extends Component {
render() {
return (
<div>
<SearchBar onSubmit={this.onSearchSubmit} />
<div>
<ImageList images={this.state.images} />
</div>
</div>
);
}
}
export default App;
Для вашего запроса Axios вместо создания всего этого кода внутри fetchActions.js
создайте структуру папок / файлов apis/unsplash.js
:
import axios from 'axios';
export default axios.create({
baseURL: 'https://api.unsplash.com'
});
Тогда внутри вашего fetchActions.js
:
export const FETCH_DATA = "fetch_data";
// Getting all images
export const getImages = inputValue => async dispatch => {
const API_KEY =
"<MY API KEY FOR UNSPLASH>";
const res = await unsplash.get(
`/search/photos?page=1&query=${inputValue}&client_id=${API_KEY}`
);
console.log(res.data.results);
dispatch({
type: "FETCH_DATA",
payload: res.data.results
});
};
Ваш combineReducers
выглядит хорошо.Ваш fetchReducer.js
, я часто вижу это в коммерческих приложениях: const initialState = {};
Это на самом деле не нужно, вырежьте этого initialState
посредника и просто:
import { FETCH_DATA } from "../actions/fetchAction";
export default function(state = {}, action) {
switch (action.type) {
case "FETCH_DATA":
return {
...state
};
default:
return state;
}
}
Хорошо, чисто,элегантный.Теперь, где использовать Connect?в App
или SearchBar
компонент?Давайте спросим себя, какова цель функции connect
?
Давайте посмотрим, мы создали наш магазин Redux, а затем передали его в Provider
Почему мы это сделали?Ах, да, так что любой компонент внутри нашего приложения может получить доступ к хранилищу Redux через тег Provider
.
Другими словами, получить доступ к некоторым данным.Так какой компонент должен получить доступ к некоторым данным?App
?Нет, не совсем, он является родительским компонентом в иерархии и просто хорошо держит все остальные компоненты, верно?
Но наши SearchBar
, мы собираемся получить доступ к некоторым данным через эту панель поиска,верно?
Теперь компонент SearchBar
может быть не единственным компонентом, где вам может понадобиться функция connect
, но я бы начал с импорта:
import { connect } from 'react-redux';
вверху SearchBar
, затем внизу SearchBar
Я бы реализовал:
export default connect()(SearchBar)
Что в мире ?!Почему у нас есть второй набор скобок вокруг SearchBar
?!
Поскольку я пытался объяснить бывшему студенту, который пожаловался администраторам, что я некомпетентен, чтобы предложить ту самую строку кода, которую вы видите вышеэта строка кода ничем не отличается от этого:
function connect() {
return function() {
return 'howdy!';
}
}
connect();
О боже, функция, которая возвращает функцию, но подождите, она ничего не печатает!
Но еслиЯ сразу добавляю вторые скобки:
function connect() {
return function() {
return 'howdy!';
}
}
connect()();
Я получаю отпечаток из howdy!
Все, что мы здесь делаем, это возвращаем функцию, и когда мы вызываем функцию, которая возвращаетсямы помещаем второй набор скобок после него, поэтому второй набор скобок вызывает функцию, которая была возвращена.
Что касается вашего mapStateToProps
, то здесь чего-то не хватает, я думаю, это должно выглядеть так:
const mapStateToProps = state => {
return { images: state.images };
};