如何基于Redux数据在通用Header组件中添加类

时间:2018-12-11 08:02:55

标签: reactjs redux react-redux

在我的react JS应用程序中,我在标头组件中添加了一个通知图标。我创建了一个单独的组件,在其中进行api调用以获取数据并显示它。我要在这里实现的是,如果有一些通知警报,则更改Header组件中图标的颜色。 我的标题组件-

import React from "react";
import { connect } from "react-redux";
import {
  setPoiData,
  getNotification,
  updateNotification
} from "../../actions/action";
import { Link } from "react-router-dom";
const axios = require("axios");

    class Notification extends React.Component {
      render() {
        const data = this.props.getNotificationStatus;
        const highlightBellIcon = Object.keys((data.length === 0))



          return (
              <div className="notification-parent">

                <Link to="/notification-details">
                  <span className={"glyphicon glyphicon-bell " + (!highlightBellIcon ? 'classA' : 'classB')} />
                </Link>
              </div>
            );
          }
        }
        const mapStateToProps = state => ({
          getNotificationStatus: state.root.getNotificationStatus
        });

        export default connect (mapStateToProps)(Notification)

在这里,getNotificationStatus是在Redux中保存值的状态。

通知细节组件-

import React from "react";
import { connect } from "react-redux";
import {
  getNotification
} from "../../actions/action";
import { Spinner } from "../Spinner";
import { setTimeout } from "timers";
import NotificationTile from "../NotificationTile/NotificationTile";

const axios = require("axios");
class NotificationDetails extends React.Component {

  componentDidMount = () => {
    this.intervalId = setInterval(() => this.handleNotification(), 2000);
    setTimeout(
      () =>
        this.setState({
          loading: false
        }),
      10000
    );
  };

  componentWillUnmount = () => {
    clearInterval(this.intervalId);
  };
  handleNotification = () => {
    let postData = {
       //inputParams
    }
    //call to action
    this.props.dispatch(getNotification(postData));
  };

  getNotificationDetails = data => {
    const payloadData =
      data.payLoad &&
      data.payLoad.map(item => {
        console.log(this);
        return <NotificationTile {...item} history={this.props.history} />;
      });
    //console.log(payloadData);
    return payloadData;
    console.log("InitialState" + payloadData);
  };
  render() {
    const { loading } = this.state;
    const data = this.props.getNotificationStatus;
    return (
      <div className="notificationContainer container">
        <div className="notification-alert">
          {!loading ? (
            this.getNotificationDetails(data)
          ) : (
            <h1>
              Waiting for notifications..
              <Spinner />
            </h1>
          )}
        </div>
      </div>
    );
  }
}
const mapStateToProps = state => ({
  getNotificationStatus: state.root.getNotificationStatus
});

export default connect(mapStateToProps)(NotificationDetails);

我面临的问题是总是添加classB,因为api调用发生在单击钟形图标时。因此,当我第一次进入页面时,除非单击响铃图标,否则不会进行api调用。我的代码绝对可以正常工作,只是我需要根据在NotificationDetail Comp中获得的响应(它是同级组件)将类添加到Notification组件(这是一个全局组件)。

2 个答案:

答案 0 :(得分:0)

当您必须基于异步调用更新REDUX存储时,您应该使用称为动作创建者的东西,这些动作创建者将使您能够 在您收到异步调用的响应后立即调度操作。

使用Redux-thunk

在下面的代码中, setTimeout 是您的异步​​调用进入的地方

const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

function increment() {
  return {
    type: INCREMENT_COUNTER
  };
}

function incrementAsync() {
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment());
    }, 1000);
  };
}

更新您的 REDUX商店,然后从 componentDidMount()调用此操作创建者 这样您就可以在第一时间收到通知。

答案 1 :(得分:0)

notification-details是一个单独的组件,可提取数据并将其添加到存储和 <Link to="/notification-details">会加载此组件,在这种情况下,就是您的商店 直到您单击响铃图标,这才是正确的行为。

解决方案:

请在您的组件树中上一步,我的意思是转到优于 通知(其容器组件),并在其中加载 notification-details (您可以使用任何创建生命周期挂钩), ,也有一个标志(类似 isNotificationLoaded ),用于检查 state.root.getNotificationStatus 的位置 填充数据并仅在设置为true后才加载“通知”面板。

类似

render() {
 const data = this.props.getNotificationStatus;
 const noticationPanel = data.length > 0 ? <Notification/> : null;

 return({noticationPanel});
}

这将确保仅在有数据时才加载,直到那时 您可以显示一些活动指示器。

希望这有助于解决您的问题。