将有状态 React 组件转换为无状态功能组件:如何实现 "componentDidMount" 种功能?
Converting stateful React component to stateless functional component: How to implement "componentDidMount" kind of functionality?
我写了一个小的有状态 React 组件。加载此组件时,在 componentDidMount
方法中,我使用 Kendo UI 在弹出窗口中显示组件的内容 window.
这是我的代码:
export class ErrorDialog extends React.Component {
constructor(props, context) {
super(props, context);
this.errorPopupWindow = null;
window.addEventListener('resize', this.resizeComponent);
this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
this.handleButtonCloseWindowOnClick = this.handleButtonCloseWindowOnClick.bind(this);
this.handleButtonShowDetailsOnClick = this.handleButtonShowDetailsOnClick.bind(this);
$('#ErrorInformationForm-CloseWindow').focus();
}
render() {
const errorInformation = this.props.errorInformation;
const baseException = errorInformation.baseException;
const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
&& typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
&& baseException.message !== '') ? true : false;
const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';
return(
<div id="Error-Dialog-Popup" onKeyDown={this.handleWindowKeyDown}>
<div className="ce-window-body">
{errorInformation.message}
<code>
<textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
</code>
</div>
</div>
);
}
componentDidMount() {
const errorInformation = this.props.errorInformation;
const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
$('#Error-Dialog-Popup').kendoWindow({
actions: [],
width: 500,
height: 130,
visible: true,
modal: true,
title: modalWindowTitle,
resizable: false
});
this.resizeComponent();
}
resizeComponent() {
}
closeWindowIfPossible(evt) {
}
handleWindowKeyDown(evt) {
}
handleButtonShowDetailsOnClick(evt) {
}
handleButtonCloseWindowOnClick(evt) {
}
}
鉴于此组件不需要维护任何状态,我正在尝试将此组件转换为无状态功能组件。
我纠结的地方是如何实现componentDidMount功能?这是我到目前为止编写的代码:
export const ErrorDialog = (props, context) => {
const errorInformation = props.errorInformation;
const baseException = errorInformation.baseException;
const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
&& typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
&& baseException.message !== '') ? true : false;
const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';
const resizeComponent = () => {
}
const closeWindowIfPossible = (evt) => {
}
const handleWindowKeyDown = (evt) => {
}
const handleButtonShowDetailsOnClick = (evt) => {
}
const handleButtonCloseWindowOnClick = (evt) => {
}
const handleComponentOnLoad = (evt) => {
console.log('comes in onLoad');
const errorInformation = props.errorInformation;
const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
$('#Error-Dialog-Popup').kendoWindow({
actions: [],
width: 500,
height: 130,
visible: true,
modal: true,
title: modalWindowTitle,
resizable: false
});
resizeComponent();
}
return(
<div id="Error-Dialog-Popup" onLoad={handleComponentOnLoad} onKeyDown={handleWindowKeyDown}>
<div className="ce-window-body">
{errorInformation.message}
<code>
<textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
</code>
</div>
</div>
);
}
起初,我以为我可以在 div 的 onLoad
事件处理程序中实现 componentDidMount
类功能,但是当我尝试这样做时,我注意到事件没有被触发完全没有(然后我阅读了文档,发现我不能真正使用这个事件:))。
所以我的问题是:
- 有没有办法在无状态功能组件中实现
componentDidMount
类功能?本质上我需要做的是在 DOM. 中加载组件时对其进行处理
- 在无状态功能组件的情况下,我正在尝试做的是一个有效的场景,还是我应该坚持使用标准组件?
函数式无状态组件没有生命周期方法。在这种情况下,您应该坚持使用标准组件。
来自 React 的 documentation:
These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods.
他们所说的(以上),但也考虑制作一个有状态的组件容器并将 props/args 传递给无状态的子组件。
在 React 16.8 中,您现在可以使用 State Hooks for functional components. For componentDidMount
, it's recommended to use Effect Hooks。
import React, { useState, useEffect } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
演示:https://codepen.io/rjruizes/pen/yLMZPvR
如果你想让Effect Hook挂载后只运行,使用空数组作为条件:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []);
我写了一个小的有状态 React 组件。加载此组件时,在 componentDidMount
方法中,我使用 Kendo UI 在弹出窗口中显示组件的内容 window.
这是我的代码:
export class ErrorDialog extends React.Component {
constructor(props, context) {
super(props, context);
this.errorPopupWindow = null;
window.addEventListener('resize', this.resizeComponent);
this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
this.handleButtonCloseWindowOnClick = this.handleButtonCloseWindowOnClick.bind(this);
this.handleButtonShowDetailsOnClick = this.handleButtonShowDetailsOnClick.bind(this);
$('#ErrorInformationForm-CloseWindow').focus();
}
render() {
const errorInformation = this.props.errorInformation;
const baseException = errorInformation.baseException;
const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
&& typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
&& baseException.message !== '') ? true : false;
const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';
return(
<div id="Error-Dialog-Popup" onKeyDown={this.handleWindowKeyDown}>
<div className="ce-window-body">
{errorInformation.message}
<code>
<textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
</code>
</div>
</div>
);
}
componentDidMount() {
const errorInformation = this.props.errorInformation;
const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
$('#Error-Dialog-Popup').kendoWindow({
actions: [],
width: 500,
height: 130,
visible: true,
modal: true,
title: modalWindowTitle,
resizable: false
});
this.resizeComponent();
}
resizeComponent() {
}
closeWindowIfPossible(evt) {
}
handleWindowKeyDown(evt) {
}
handleButtonShowDetailsOnClick(evt) {
}
handleButtonCloseWindowOnClick(evt) {
}
}
鉴于此组件不需要维护任何状态,我正在尝试将此组件转换为无状态功能组件。
我纠结的地方是如何实现componentDidMount功能?这是我到目前为止编写的代码:
export const ErrorDialog = (props, context) => {
const errorInformation = props.errorInformation;
const baseException = errorInformation.baseException;
const showExceptionMessage = (typeof baseException !== 'undefined' && typeof baseException === 'object' && baseException !== null
&& typeof baseException.message !== 'undefined' && typeof baseException.message === 'string' && baseException.message !== null
&& baseException.message !== '') ? true : false;
const baseExceptionMessage = showExceptionMessage ? baseException.message : '';
const exceptionMessageCss = showExceptionMessage ? 'k-textbox ce-width-100-pct ce-margin-top-5' : 'ce-invisible';
const resizeComponent = () => {
}
const closeWindowIfPossible = (evt) => {
}
const handleWindowKeyDown = (evt) => {
}
const handleButtonShowDetailsOnClick = (evt) => {
}
const handleButtonCloseWindowOnClick = (evt) => {
}
const handleComponentOnLoad = (evt) => {
console.log('comes in onLoad');
const errorInformation = props.errorInformation;
const modalWindowTitle = '<span class="ce-width-100-pct ce-app-color-red"><i class="fa ce-fs-1-2-5x fa-times-circle"></i> ' + errorInformation.heading + '</span>';
$('#Error-Dialog-Popup').kendoWindow({
actions: [],
width: 500,
height: 130,
visible: true,
modal: true,
title: modalWindowTitle,
resizable: false
});
resizeComponent();
}
return(
<div id="Error-Dialog-Popup" onLoad={handleComponentOnLoad} onKeyDown={handleWindowKeyDown}>
<div className="ce-window-body">
{errorInformation.message}
<code>
<textarea readOnly={true} className={exceptionMessageCss} rows="3" defaultValue={baseExceptionMessage} />
</code>
</div>
</div>
);
}
起初,我以为我可以在 div 的 onLoad
事件处理程序中实现 componentDidMount
类功能,但是当我尝试这样做时,我注意到事件没有被触发完全没有(然后我阅读了文档,发现我不能真正使用这个事件:))。
所以我的问题是:
- 有没有办法在无状态功能组件中实现
componentDidMount
类功能?本质上我需要做的是在 DOM. 中加载组件时对其进行处理
- 在无状态功能组件的情况下,我正在尝试做的是一个有效的场景,还是我应该坚持使用标准组件?
函数式无状态组件没有生命周期方法。在这种情况下,您应该坚持使用标准组件。
来自 React 的 documentation:
These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods.
他们所说的(以上),但也考虑制作一个有状态的组件容器并将 props/args 传递给无状态的子组件。
在 React 16.8 中,您现在可以使用 State Hooks for functional components. For componentDidMount
, it's recommended to use Effect Hooks。
import React, { useState, useEffect } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
演示:https://codepen.io/rjruizes/pen/yLMZPvR
如果你想让Effect Hook挂载后只运行,使用空数组作为条件:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []);