簡體   English   中英

當React 16中不贊成`this.refs`時,如何使用`mainPanel`?

[英]How to use `mainPanel` when `this.refs` is deprecated in React 16?

我有一個Dashboard.js

這是我的代碼

import React from "react";
import cx from "classnames";
import PropTypes from "prop-types";
import {Switch, Route, Redirect, withRouter} from "react-router-dom";
import {browserHistory} from 'react-router';
// creates a beautiful scrollbar
import PerfectScrollbar from "perfect-scrollbar";
import "perfect-scrollbar/css/perfect-scrollbar.css";

// @material-ui/core components
import withStyles from "@material-ui/core/styles/withStyles";

// core components
import Header from "components/Header/Header.jsx";
import Footer from "components/Footer/Footer.jsx";
import Sidebar from "components/Sidebar/Sidebar.jsx";

import dashboardRoutes from "routes/dashboard.jsx";

import appStyle from "assets/jss/material-dashboard-pro-react/layouts/dashboardStyle.jsx";

import image from "assets/img/sidebar-2.jpg";
import logo from "assets/img/logo-white.svg";

const switchRoutes = (
  <Switch>
    {dashboardRoutes.map((prop, key) => {
      if (prop.redirect)
        return <Redirect from={prop.path} to={prop.pathTo} key={key}/>;
      if (prop.contain && prop.views)
        return prop.views.map((prop, key) => {
          return (
            <Route path={prop.path} component={prop.component} key={key}/>
          );
        });
      if (prop.collapse && prop.views)
        return prop.views.map((prop, key) => {
          if (prop.contain && prop.views)
            return prop.views.map((prop, key) => {
              return (
                <Route path={prop.path} component={prop.component} key={key}/>
              );
            });
          return (
            <Route path={prop.path} component={prop.component} key={key}/>
          );
        });
      return <Route path={prop.path} component={prop.component} key={key}/>;
    })}
  </Switch>
);

var ps;

class Dashboard extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      mobileOpen: false,
      miniActive: false,
      logged_in: localStorage.getItem('token') ? true : false,
    };
    this.resizeFunction = this.resizeFunction.bind(this);
  }

  componentDidMount() {
    if (!this.state.logged_in) {
      browserHistory.push("/accounts/login");
    }
    if (navigator.platform.indexOf("Win") > -1) {
      ps = new PerfectScrollbar(this.refs.mainPanel, {
        suppressScrollX: true,
        suppressScrollY: false
      });
      document.body.style.overflow = "hidden";
    }
    window.addEventListener("resize", this.resizeFunction);
  }

  componentWillUnmount() {
    if (navigator.platform.indexOf("Win") > -1) {
      ps.destroy();
    }
    window.removeEventListener("resize", this.resizeFunction);
  }

  componentDidUpdate(e) {
    if (e.history.location.pathname !== e.location.pathname) {
      this.refs.mainPanel.scrollTop = 0;
      if (this.state.mobileOpen) {
        this.setState({mobileOpen: false});
      }
    }
  }

  handleDrawerToggle = () => {
    this.setState({mobileOpen: !this.state.mobileOpen});
  };

  getRoute() {
    return this.props.location.pathname !== "/maps/full-screen-maps";
  }

  sidebarMinimize() {
    this.setState({miniActive: !this.state.miniActive});
  }

  resizeFunction() {
    if (window.innerWidth >= 960) {
      this.setState({mobileOpen: false});
    }
  }

  render() {
    const {classes, ...rest} = this.props;
    const mainPanel =
      classes.mainPanel +
      " " +
      cx({
        [classes.mainPanelSidebarMini]: this.state.miniActive,
        [classes.mainPanelWithPerfectScrollbar]:
        navigator.platform.indexOf("Win") > -1
      });
    return (
      <div className={classes.wrapper}>
        <Sidebar
          routes={dashboardRoutes}
          logoText={"ENO A3"}
          logo={logo}
          image={image}
          handleDrawerToggle={this.handleDrawerToggle}
          open={this.state.mobileOpen}
          color="blue"
          bgColor="black"
          miniActive={this.state.miniActive}
          {...rest}
        />
        <div className={mainPanel} ref="mainPanel">
          <Header
            sidebarMinimize={this.sidebarMinimize.bind(this)}
            miniActive={this.state.miniActive}
            routes={dashboardRoutes}
            handleDrawerToggle={this.handleDrawerToggle}
            {...rest}
          />
          {/* On the /maps/full-screen-maps route we want the map to be on full screen - this is not possible if the content and conatiner classes are present because they have some paddings which would make the map smaller */}
          {this.getRoute() ? (
            <div className={classes.content}>
              <div className={classes.container}>{switchRoutes}</div>
            </div>
          ) : (
            <div className={classes.map}>{switchRoutes}</div>
          )}
          {this.getRoute() ? <Footer fluid/> : null}
        </div>
      </div>
    );
  }
}

Dashboard.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withRouter(withStyles(appStyle)(Dashboard));

我對抱怨ref屬性的棄用不屑一顧。

所以我有關於這條線的抱怨

<div className={mainPanel} ref="mainPanel">

ps = new PerfectScrollbar(this.refs.mainPanel, {

我該如何重寫它以克服這些棄用?

UPDATE

將所有this.refs.mainPanel更改為this.mainPanel ,出現以下錯誤:

Uncaught TypeError: Cannot add property scrollTop, object is not extensible at Dashboard.componentDidUpdate (Dashboard.js:170)

這指的是

 this.refs.mainPanel.scrollTop = 0;

現在變成

this.mainPanel.scrollTop = 0;

首先,您需要在構造函數中創建ref(因為您正在使用構造函數):

constructor(props) {
  super(props);
  this.state = {
    mobileOpen: false,
    miniActive: false,
    logged_in: localStorage.getItem('token') ? true : false,
  };
  this.resizeFunction = this.resizeFunction.bind(this);
  this.mainPanel = React.createRef();
}

然后像這樣使用它:

<div className={mainPanel} ref={this.mainPanel} >

相關文檔。

更新React 16之后,我遇到了同樣的問題。實際上,解決起來很簡單:從React Docs

當將ref傳遞到渲染中的元素時,可以在ref的當前屬性處訪問對節點的引用。

因此,在構造函數中創建ref並將其附加到元素后,訪問ref所需要做的就是使用: this.mainPanel.current.scrollTop

這將有助於避免出現“不可擴展對象”錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM