Давайте попробуем оптимизировать ваш поток реакции-избыточности здесь, чтобы мы могли немного проще объяснить.
Сначала давайте попробуем сделать так, чтобы ваш компонент приложения выглядел так:
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, combineReducers } from "redux";
import articles from "./reducers/articles";
import Articles from "./components/Articles";
import Preview from "./components/Preview";
const store = createStore(
combineReducers({
articles: articles
})
);
function App() {
return (
<Provider store={store}>
<div className="App">
<Articles />
<Preview />
</div>
</Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Основной компонент отображает компоненты «Статьи» и «Предварительный просмотр». Кроме того, мы передаем избыточное хранилище основному компоненту.
Давайте рассмотрим все аспекты, которые составляют наше избыточное хранилище.
redurs.js
const initialState = {
articles: [
{
title: "Corgi",
url: "https://www.akc.org/dog-breeds/cardigan-welsh-corgi/"
},
{
title: "Leopard Dog",
url: "https://www.akc.org/dog-breeds/catahoula-leopard-dog/"
}
],
article: {}
};
const articlesReducer = (state = initialState, action) => {
switch (action.type) {
case "SHOW_URL":
return {
...state,
article: action.payload
};
default:
return state;
}
};
export default articlesReducer;
В редукторе у нас есть состояние по умолчанию, которое содержит массив объектов (статей) и текущую статью. Мы будем использовать оба для заполнения отображения наших статей и компонентов Preview. Наш редуктор обновляется только тогда, когда отправляется действие с типом «SHOW_URL», и, таким образом, мы будем обновлять текущую статью.
См. Создатель действий в actions.js :
export const showUrl = article => {
return {
type: "SHOW_URL",
payload: article
};
};
Теперь для наших компонентов Статьи , Артикул и Предварительный просмотр .
В статьях мынужно использовать mapStateToProps , чтобы получить список статей, доступных в нашем Redux-состоянии. Затем мы перебираем каждую статью и визуализируем отдельный компонент Article
. Передача, повторяющаяся статья как опора.
import React from "react";
import { connect } from "react-redux";
import Article from "./Article";
const Articles = ({ articles }) => {
return (
<div>
{articles.articles.map(article => {
return <Article article={article} />;
})}
</div>
);
};
const mapStateToProps = state => {
return {
articles: state.articles
};
};
export default connect(mapStateToProps)(Articles);
Теперь в каждом уникальном компоненте Article мы используем нашего создателя действия, передавая статью, которую мы получили в качестве опоры, для обновления избыточного состояния.
import React from "react";
import { connect } from "react-redux";
import { showUrl } from "../actions/articleActions";
const Article = ({ article, showUrl }) => {
return (
<div>
<button onClick={() => showUrl(article)}>{article.title}</button>
</div>
);
};
const mapDispatchToProps = dispatch => {
return {
showUrl: article => {
dispatch(showUrl(article));
}
};
};
export default connect(
null,
mapDispatchToProps
)(Article);
Когда действие завершается, наш редуктор получает обновленное состояние, в результате чего наш Preview
компонент повторно выполняет рендеринг и отражает эти обновленные данные.
import React from "react";
import { connect } from "react-redux";
const Preview = ({ articles }) => {
const thisArticle = articles.article;
return (
<div>
<h4>{thisArticle.title}</h4>
<a href={thisArticle.url}>Go To Link</a>
</div>
);
};
const mapStateToProps = state => {
return {
articles: state.articles
};
};
export default connect(mapStateToProps)(Preview);
Я создалобразцы кодов и коробка для вас здесь для справки: https://codesandbox.io/s/simple-redux-with-dogs-s1v6h