react-console-emulator开发模式下欢迎消息重复渲染问题求助
解决react-console-emulator在Next.js开发模式下欢迎消息重复渲染的问题
我用react-console-emulator制作类终端风格的作品集网站,开发模式下欢迎消息会渲染两次(生产构建完成后仅渲染一次),但组件文档说明该消息应仅显示一次。相关代码如下:
import React from 'react' import Terminal from 'react-console-emulator' const commands = { echo: { description: 'Echo a passed string.', usage: 'echo <string>', fn: function () { return `${Array.from(arguments).join(' ')}` } } } export default class MyTerminal extends React.Component { render () { return ( <Terminal commands={commands} style={{ backgroundColor: null, minHeight: "100vh", height: '100%', maxHeight: "100vh", overflow: 'auto', width: '100%', padding: "10px 0px", fontFamily: "Hack" }} welcomeMessage={'Welcome to the React terminal!'} promptLabel={'me@React:~$'} contentStyle={{ color: 'var(--th-primary)', fontWeight: 'normal', paddingLeft: null, fontFamily: "Hack" }} promptLabelStyle={{ color: 'var(--th-primary)', fontWeight: 'normal', paddingTop: null, fontFamily: "Hack" }} inputTextStyle={{ color: 'var(--th-secondary)', fontWeight: 'normal', paddingTop: null, fontFamily: "Hack" }} messageStyle={{ color: 'var(--th-secondary)', fontWeight: 'normal', paddingLeft: null, fontFamily: "Hack" }} /> ) } }
问题原因
这是Next.js开发模式下的Strict Mode导致的。Strict Mode为了检测组件潜在的副作用,会在开发环境中额外执行一次组件挂载、生命周期方法(如类组件的componentDidMount)。react-console-emulator内部通过组件挂载逻辑添加欢迎消息,重复挂载就会触发两次添加操作,最终显示两条欢迎消息。
解决方案
方案1:禁用Strict Mode(快速临时解决)
在next.config.js中修改配置,关闭React Strict Mode:
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, // 其他项目配置... } module.exports = nextConfig
或在pages/_app.js(App Router对应app/layout.js)中移除<React.StrictMode>的包裹。
方案2:手动控制欢迎消息添加(推荐,保留Strict Mode)
放弃组件自带的welcomeMessage属性,改为在组件挂载时手动添加欢迎消息,同时通过标记确保只执行一次:
import React from 'react' import Terminal from 'react-console-emulator' const commands = { echo: { description: 'Echo a passed string.', usage: 'echo <string>', fn: function () { return `${Array.from(arguments).join(' ')}` } } } export default class MyTerminal extends React.Component { terminalRef = React.createRef() hasAddedWelcome = false componentDidMount() { // 仅在首次挂载时添加欢迎消息 if (!this.hasAddedWelcome && this.terminalRef.current) { this.terminalRef.current.log('Welcome to the React terminal!') this.hasAddedWelcome = true } } render () { return ( <Terminal ref={this.terminalRef} commands={commands} style={{ backgroundColor: null, minHeight: "100vh", height: '100%', maxHeight: "100vh", overflow: 'auto', width: '100%', padding: "10px 0px", fontFamily: "Hack" }} // 移除自带的welcomeMessage属性 promptLabel={'me@React:~$'} contentStyle={{ color: 'var(--th-primary)', fontWeight: 'normal', paddingLeft: null, fontFamily: "Hack" }} promptLabelStyle={{ color: 'var(--th-primary)', fontWeight: 'normal', paddingTop: null, fontFamily: "Hack" }} inputTextStyle={{ color: 'var(--th-secondary)', fontWeight: 'normal', paddingTop: null, fontFamily: "Hack" }} messageStyle={{ color: 'var(--th-secondary)', fontWeight: 'normal', paddingLeft: null, fontFamily: "Hack" }} /> ) } }
内容的提问来源于stack exchange,提问作者Ashish Kumar
相关产品推荐
相关产品推荐

