Реагируйте: Как обновить один компонент, когда что-то происходит на другом компоненте - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть приложение с таблицей, в таблице есть флажок для установки Арендатора как Активного, эта переменная является глобальной переменной, которая влияет на действия пользователя в других экранах приложения.

НаВ правом верхнем углу приложения у меня есть другой компонент под названием ActiveTenant, который в основном показывает, в каком арендаторе пользователь работает в данный момент.

enter image description here

Кодкомпонента таблицы выглядит следующим образом:

import React, { Component } from 'react';
import {  Table, Radio} from 'antd';
import { adalApiFetch } from '../../adalConfig';
import Notification from '../../components/notification';

class ListTenants extends Component {

    constructor(props) {
        super(props);
        this.state = {
            data: []
        };
    }



    fetchData = () => {
        adalApiFetch(fetch, "/Tenant", {})
          .then(response => response.json())
          .then(responseJson => {
            if (!this.isCancelled) {
                const results= responseJson.map(row => ({
                    key: row.id,
                    TestSiteCollectionUrl: row.TestSiteCollectionUrl,
                    TenantName: row.TenantName,
                    Email: row.Email
                  }))
              this.setState({ data: results });
            }
          })
          .catch(error => {
            console.error(error);
          });
      };


    componentDidMount(){
        this.fetchData();
    }

    render() {
        const columns = [
                {
                    title: 'TenantName',
                    dataIndex: 'TenantName',
                    key: 'TenantName',
                }, 
                {
                    title: 'TestSiteCollectionUrl',
                    dataIndex: 'TestSiteCollectionUrl',
                    key: 'TestSiteCollectionUrl',
                }, 
                {
                    title: 'Email',
                    dataIndex: 'Email',
                    key: 'Email',
                }
        ];

        // rowSelection object indicates the need for row selection
        const rowSelection = {
            onChange: (selectedRowKeys, selectedRows) => {
                if(selectedRows[0].TenantName != undefined){
                    console.log(selectedRows[0].TenantName);
                    const options = { 
                        method: 'post'
                    };

                    adalApiFetch(fetch, "/Tenant/SetTenantActive?TenantName="+selectedRows[0].TenantName.toString(), options)
                        .then(response =>{
                        if(response.status === 200){
                            Notification(
                                'success',
                                'Tenant set to active',
                                ''
                                );
                        }else{
                            throw "error";
                        }
                        })
                        .catch(error => {
                        Notification(
                            'error',
                            'Tenant not activated',
                            error
                            );
                        console.error(error);
                    });
                }
            },
            getCheckboxProps: record => ({
                type: Radio
            }),
        };

        return (
            <Table rowSelection={rowSelection} columns={columns} dataSource={this.state.data} />
        );
    }
}

export default ListTenants;

И код компонента ActiveTenant также очень прост

import React, { Component } from 'react';
import authAction from '../../redux/auth/actions';
import { adalApiFetch } from '../../adalConfig';

class ActiveTenant extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tenant: ''
    };
  }

  fetchData = () => {
    adalApiFetch(fetch, "/Tenant/GetActiveTenant", {})
      .then(response => response.json())
      .then(responseJson => {
        if (!this.isCancelled) {
          this.setState({ tenant: responseJson.TenantName });
        }
      })
      .catch(error => {
        this.setState({ tenant: '' });
        console.error(error);
      });
  };


componentDidMount(){
    this.fetchData();
}

  render() {
    return (
      <div>You are using tenant: {this.state.tenant }</div>
    );
  }
}
export default ActiveTenant;

Проблема в том, что если в моей базе данных зарегистрировано несколько арендаторови я установил их активными, происходит действие на стороне сервера, и состояние изменяется, однако в правом верхнем углу он все еще показывает, что старый арендатор активен, пока я не нажму F5, чтобы обновить браузер.

Как можноЯ добиваюсь этого?

Ради полного понимания моего кода мне нужно будет вставить следующие компоненты:

  1. TopBar, которыйсодержит активного арендатора

    import React, { Component } from "react";
    import { connect } from "react-redux";import { Layout } from "antd";
    import appActions from "../../redux/app/actions";
    import TopbarUser from "./topbarUser";
    import TopbarWrapper from "./topbar.style";
    import ActiveTenant from "./activetenant";
    import TopbarNotification from './topbarNotification';
    
    
    const { Header } = Layout;
    const { toggleCollapsed } = appActions;
    
    class Topbar extends Component {
      render() {
        const { toggleCollapsed, url, customizedTheme, locale } = this.props;
        const collapsed = this.props.collapsed && !this.props.openDrawer;
        const styling = {
          background: customizedTheme.backgroundColor,
          position: 'fixed',
          width: '100%',
          height: 70
        };
        return (
          <TopbarWrapper>
            <Header
              style={styling}
              className={
                collapsed ? "isomorphicTopbar collapsed" : "isomorphicTopbar"
              }
            >
              <div className="isoLeft">
                <button
                  className={
                    collapsed ? "triggerBtn menuCollapsed" : "triggerBtn menuOpen"
                  }
                  style={{ color: customizedTheme.textColor }}
                  onClick={toggleCollapsed}
                />
              </div>
    
              <ul className="isoRight">
                <li
                  onClick={() => this.setState({ selectedItem: 'notification' })}
                  className="isoNotify"
                >
                  <TopbarNotification locale={locale} />
                </li>
                <li>
                  <ActiveTenant />
                </li>
                <li
                  onClick={() => this.setState({ selectedItem: "user" })}
                  className="isoUser"
                >
                  <TopbarUser />
                  <div>{ process.env.uiversion}</div>
                </li>
              </ul>
            </Header>
          </TopbarWrapper>
        );
      }
    }
    
    export default connect(
      state => ({
        ...state.App.toJS(),
        locale: state.LanguageSwitcher.toJS().language.locale,
        customizedTheme: state.ThemeSwitcher.toJS().topbarTheme
      }),
      { toggleCollapsed }
    )(Topbar);
    

App.js, который содержит верхнюю строку

import React, { Component } from "react";
import { connect } from "react-redux";
import { Layout, LocaleProvider } from "antd";
import { IntlProvider } from "react-intl";
import { Debounce } from "react-throttle";
import WindowResizeListener from "react-window-size-listener";
import { ThemeProvider } from "styled-components";
import authAction from "../../redux/auth/actions";
import appActions from "../../redux/app/actions";
import Sidebar from "../Sidebar/Sidebar";
import Topbar from "../Topbar/Topbar";
import AppRouter from "./AppRouter";
import { siteConfig } from "../../settings";
import themes from "../../settings/themes";
import { themeConfig } from "../../settings";
import AppHolder from "./commonStyle";
import "./global.css";
import { AppLocale } from "../../dashApp";
import ThemeSwitcher from "../../containers/ThemeSwitcher";



const { Content, Footer } = Layout;
const { logout } = authAction;
const { toggleAll } = appActions;
export class App extends Component {
  render() {
    const { url } = this.props.match;
    const { locale, selectedTheme, height } = this.props;
    const currentAppLocale = AppLocale[locale];
    return (
      <LocaleProvider locale={currentAppLocale.antd}>
      <IntlProvider
        locale={currentAppLocale.locale}
        messages={currentAppLocale.messages}
      >
      <ThemeProvider theme={themes[themeConfig.theme]}>
        <AppHolder>
          <Layout style={{ height: "100vh" }}>
            <Debounce time="1000" handler="onResize">
              <WindowResizeListener
                onResize={windowSize =>
                  this.props.toggleAll(
                    windowSize.windowWidth,
                    windowSize.windowHeight
                  )
                }
              />
            </Debounce>
            <Topbar url={url} />
            <Layout style={{ flexDirection: "row", overflowX: "hidden" }}>
              <Sidebar url={url} />
              <Layout
                className="isoContentMainLayout"
                style={{
                  height: height
                }}
              >
                <Content
                  className="isomorphicContent"
                  style={{
                    padding: "70px 0 0",
                    flexShrink: "0",
                    background: "#f1f3f6",
                    position: "relative"
                  }}
                >
                  <AppRouter url={url} />
                </Content>
                <Footer
                  style={{
                    background: "#ffffff",
                    textAlign: "center",
                    borderTop: "1px solid #ededed"
                  }}
                >
                  {siteConfig.footerText}
                </Footer>
              </Layout>
            </Layout>
            <ThemeSwitcher />
          </Layout>
        </AppHolder>
      </ThemeProvider>
      </IntlProvider>
      </LocaleProvider>
    );
  }
}

export default connect(
  state => ({
    auth: state.Auth,
    locale: state.LanguageSwitcher.toJS().language.locale,
    selectedTheme: state.ThemeSwitcher.toJS().changeThemes.themeName,
    height: state.App.toJS().height
  }),
  { logout, toggleAll }
)(App);

Я думаю, этого должно быть достаточно, чтобы проиллюстрировать мой вопрос.

1 Ответ

0 голосов
/ 27 февраля 2019

Вы неправильно используете там редукс.Вы должны держать где-то в своем состоянии избыточности вашего активного арендатора;Эта информация будет вашим единственным источником правды и будет распространяться среди ваших компонентов по всему приложению.Каждый компонент, который будет нуждаться в этой информации, будет связан с этой частью состояния, и ему не нужно будет хранить внутреннее состояние для этой информации.

Действия , где вы бы назвали свойAPI, чтобы получить информацию об активном арендаторе или установить нового арендатора в качестве активного.Эти действия вызовут redurs , которые изменят ваше состояние избыточности (включая информацию об активном арендаторе), и эти изменения состояния избыточности обновят компоненты вашего приложения.

Возможно, вам потребуется некоторое время, чтобы прочитатьили перечитайте DOC , это коротко и хорошо объяснено!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...