Как получить реквизит с помощью onClick и передать с компонентом в Redux? - PullRequest
0 голосов
/ 29 сентября 2019

Я изучаю излишний и я изо всех сил пытаюсь понять это. У меня есть список статей, и каждая статья содержит заголовок и URL. Я хотел бы получить URL-адрес текущей статьи и передать его другому компоненту для показа URL-адреса предварительного просмотра

Я пытаюсь передать URL-адрес текущей статьи, когда нажимаю кнопку, чтобы надеть другуюкомпонент в Article.js, но он не работает. это только показать все URL всей статьи. Если кто-то может помочь мне или объяснить мне, в чем я не прав, это может быть очень приятно.

в actions.js


export const articleClick = url => ({
    type: SHOW_ARTCILE,
    payload: { url }
});

в избыточном, article.js

  article: null
}

const articleReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case 'SHOW_ARTCILE':
      return [
        ...state,
        {
          url: action.url,
        }
      ]
        ;
    default:
      return state;
  }
}

export default articleReducer;

в Article.js

import { articleClick } from '../../redux/actions';
import { connect } from "react-redux";

class Article extends Component {

  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <p>{this.props.article.title}</p>
        <div>
          <p>Posted by : {this.props.article.by}</Posted>
          <button onClick={() => this.props.articleClick(this.props.article.url), console.log(this.props.article.url)}>Visit website</button>
        </div>
      </div>
    )
  }
}

export default connect(
  null,
  { articleClick }
)(Article);

в Preview.js

import { connect } from "react-redux";
import { articleClick } from '../../redux/actions';

class PreviewArticle extends Component {
  render() {
    return (
      <p>
        {this.url}
      </p>
    );
  }
}

export default connect(
  null,
  { articleClick }
)(PreviewArticle);


1 Ответ

1 голос
/ 30 сентября 2019

Давайте попробуем оптимизировать ваш поток реакции-избыточности здесь, чтобы мы могли немного проще объяснить.

Сначала давайте попробуем сделать так, чтобы ваш компонент приложения выглядел так:

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

...