在函数助手中调用redux操作

时间:2019-05-16 00:06:13

标签: reactjs react-redux

我正在尝试创建警报组件,但是为此,我需要(从任何地方)向该状态的警报列表中添加一个项目。

我有以下代码: alertReducer.js:

import { SET_ALERT, GET_ALERTS, SET_ALERT_SHOWED } from "../actions/types";

const initialState = {
  alerts: [
    {
      id: 0,
      title: "teste",
      message: "teste",
      isShowed: false,
      type: "success"
    }
  ]
};

export default function(state = initialState, action) {
  switch (action.type) {
    case SET_ALERT:
      return { ...state, alert: action.payload };
    case SET_ALERT_SHOWED:
      return {
        ...state,
        alert: state.alerts.map(a =>
          a.id === a.payload.id ? (a = action.payload) : a
        )
      };
    case GET_ALERTS:
      return { ...state };
    default:
      return state;
  }
}

alertActions.js

import { SET_ALERT, GET_ALERTS, SET_ALERT_SHOWED } from "./types";
import axios from "axios";

export const getAlerts = () => dispatch => {
  dispatch({
    type: GET_ALERTS,
    payload: null
  });
};

export const setAlertShowed = alert => dispatch => {
  dispatch({
    type: SET_ALERT_SHOWED,
    payload: null
  });
};

export const setAlert = alert => dispatch => {
  console.log("set alert:");

  this.setState(state => {
    state.alert.alerts.push(alert);
    return null;
  });

  dispatch({
    type: SET_ALERT,
    payload: null
  });
};

alerts.js(组件)

import React from "react";
import { Link } from "react-router-dom";
import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import {
  Panel,
  PanelHeader,
  PanelBody
} from "./../../components/panel/panel.jsx";
import SweetAlert from "react-bootstrap-sweetalert";
import ReactNotification from "react-notifications-component";
import "react-notifications-component/dist/theme.css";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { getAlerts, setAlertShowed } from "../../actions/alertActions";

class Alerts extends React.Component {
  constructor(props) {
    super(props);
    this.addNotification = this.addNotification.bind(this);
    this.notificationDOMRef = React.createRef();
  }

  componentWillReceiveProps(nextProps) {
    console.log("atualizou alertas");
    console.log(this.props);
    console.log(nextProps);
  }

  componentDidMount() {
    this.props.getAlerts();
    this.showAlerts();
  }

  showAlerts() {
    const { alerts } = this.props;
    alerts
      .filter(a => !a.isShowed)
      .map((a, i) => {
        this.addNotification.call(this, a);
        a.isShowed = true;
        setAlertShowed(a);
      });
  }

  addNotification(alert) {
    this.notificationDOMRef.current.addNotification({
      title: alert.title,
      message: alert.message,
      type: alert.type,
      insert: "top",
      container: "top-right",
      animationIn: ["animated", "fadeIn"],
      animationOut: ["animated", "fadeOut"],
      dismiss: { duration: 2000 },
      dismissable: { click: true }
    });
  }

  render() {
    const { alerts } = this.props;

    return <ReactNotification ref={this.notificationDOMRef} />;
  }
}

Alerts.propTypes = {
  alerts: PropTypes.array.isRequired,
  getAlerts: PropTypes.func.isRequired,
  setAlertShowed: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  alerts: state.alert.alerts
});

export default connect(
  mapStateToProps,
  { getAlerts, setAlertShowed }
)(Alerts);

因此,我正在尝试使用该帮助程序,它将可以在应用程序中的任何位置触发addAlert并生成新警报,但是我不知道如何在alertActions中调用setAlert函数。 js,我能够通过store.dispatch调用SET_ALERT,但是显然这不会触发setAlert或我做错了事

import uuid from "uuid";
import { createStore } from "redux";
import { setAlert } from "../actions/alertActions";
import { SET_ALERT } from "../actions/types";
import alertReducer from "../reducers/alertReducer";

export function addAlert(state, title, message, type = "success") {
  // const store = createStore(alertReducer);
  // const state = store.getState();

  const newalert = {
    id: uuid.v4(),
    title,
    message,
    isShowed: false,
    type: type
  };

  console.log("state");
  console.log(state);
  // this.setState(state => {
  //   state.alert.alerts.push(alert);
  //   return null;
  // });

  // store.dispatch({
  //   type: SET_ALERT,
  //   payload: newalert
  // });

  // store.dispatch(setAlert(newalert));

  // store.dispatch(SET_ALERT);
  // this.setState(prevState => ({
  //   alert.alerts: [...prevState.alert.alerts, newalert]
  // }))
}

PS。我的反应知识还很低,英语不是我的主要语言,如果我不清楚的话,请问任何事情。 谢谢。

2 个答案:

答案 0 :(得分:0)

这样做:

// Create alert which you want to show
const alerts = [
{
  id: 0,
  title: "teste",
  message: "teste",
  isShowed: false,
  type: "success"
}];

componentDidMount() {
    this.props.getAlerts();
    this.showAlerts();
    // this will call alerts action
    this.props.callAlert(alerts );
  }

const mapDispatchToProps = dispatch=> ({
  callAlert: (alert) => dispatch(setAlert(alert)),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
  { getAlerts, setAlertShowed }
)(Alerts);

答案 1 :(得分:0)

最后!我通过添加compose和applyMiddleware创建了商店,我仍然必须研究它的最佳工作方式,但是它确实有效。 添加警报的帮助程序代码如下:

import uuid from "uuid";
import { createStore, dispatch, compose, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { setAlert } from "../actions/alertActions";
import alertReducer from "../reducers/alertReducer";

export function addAlert(title, message, type = "success") {
  const store = createStore(alertReducer, compose(applyMiddleware(thunk)));

  const newalert = {
    id: uuid.v4(),
    title,
    message,
    isShowed: false,
    type: type
  };

  store.dispatch(setAlert(newalert));
}