[英]Converting stateful React component to stateless functional component: How to implement "componentDidMount" kind of functionality?
I have written a small stateful React component.我写了一个小的有状态的 React 组件。 When this component loads, in
componentDidMount
method I am making use of Kendo UI to show the content of the component in a popup window.当这个组件加载时,在
componentDidMount
方法中,我使用 Kendo UI 在弹出窗口中显示组件的内容。
Here's my code:这是我的代码:
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) {
}
}
Given that this component doesn't need to maintain any state, I am trying to convert this component into a stateless functional component.鉴于此组件不需要维护任何状态,我正在尝试将此组件转换为无状态功能组件。
The place where I am struggling is how to implement componentDidMount functionality ?我挣扎的地方是如何实现 componentDidMount 功能? Here's the code I have written so far:
这是我到目前为止编写的代码:
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>
);
}
At first, I thought I could implement componentDidMount
kind of functionality in onLoad
event handler of the div but when I tried doing it I noticed that the event is not fired at all (I then read the documentation and found out that I can't really use this event :)).起初,我以为我可以在 div 的
onLoad
事件处理程序中实现componentDidMount
类型的功能,但是当我尝试这样做时,我注意到该事件根本没有被触发(然后我阅读了文档并发现我真的不能使用此事件:))。
So my questions are:所以我的问题是:
componentDidMount
kind of functionality in stateless functional components?componentDidMount
类型的功能? Essentially what I need to do is do something with the component when it is loaded in DOM.Functional stateless components do not have lifecycle methods.功能性无状态组件没有生命周期方法。 You should stick with standard component in this case.
在这种情况下,您应该坚持使用标准组件。
From React's documentation :来自 React 的文档:
These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods.
这些组件不得保留内部状态,没有后备实例,也没有组件生命周期方法。
他们所说的(上面),但也考虑制作一个有状态的组件容器并将 props/args 传递给无状态的子组件。
In React 16.8, you can now use State Hooks for functional components.在 React 16.8 中,您现在可以对功能组件使用状态挂钩。 For
componentDidMount
, it's recommended to use Effect Hooks .对于
componentDidMount
,建议使用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>
);
}
Demo: https://codepen.io/rjruizes/pen/yLMZPvR演示: https : //codepen.io/rjruizes/pen/yLMZPvR
If you want the Effect Hook to only run after mount, use an empty array as the condition:如果您希望 Effect Hook 仅在挂载后运行,请使用空数组作为条件:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.