[英]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, {
我該如何重寫它以克服這些棄用?
將所有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.