React项目npm start后页面空白问题求助
使用npx create-react-app创建项目后,尝试从index.js渲染App组件,执行npm start后页面显示空白。但删除App.js内所有组件后逐个添加并保存时,页面能正常渲染,刷新localhost后又变回空白。
相关代码
index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> );
App.js
import "./general.css"; import IntIsland from "./components/interactiveIsland"; import Home from "./paginas/Home"; import Education from "./paginas/Education"; import Portfolio from "./paginas/Portfolio"; import Contact from "./paginas/Contact"; function App() { return ( <div> <IntIsland /> <div className="todo" id="todo"> <Home /> <Education /> <Portfolio /> <Contact /> </div> </div> ); } export default App;
package.json
{ "name": "portfolio-react", "version": "0.1.0", "private": true, "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/react-fontawesome": "^0.2.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "node-sass": "^7.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.3", "react-scripts": "^5.0.1", "web-vitals": "^2.1.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
浏览器报错
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
Warning: Invalid DOM propertyfor. Did you meanhtmlFor?
触发第一个错误的代码片段:
const todo = document.getElementById("todo"); var lastScrollTop = 0; todo.addEventListener("scroll", scrollDetection); function scrollDetection() { var st = this.scrollTop(); if (st > lastScrollTop) { console.log("GOING DOWN"); } else { console.log("GOING UP"); } lastScrollTop = st; }
问题分析与解决
1. 空指针错误(addEventListener)
这段代码直接通过document.getElementById获取DOM元素,但React组件渲染是异步的,页面刷新时,执行这段代码的时机早于id="todo"的元素挂载到DOM,导致todo为null,进而触发报错。热更新时组件是增量渲染,元素已存在,所以不会报错。
修复方案:
使用React的useRef和useEffect钩子,确保元素挂载后再添加监听:
import { useRef, useEffect } from 'react'; // 在组件内部定义 const todoRef = useRef(null); useEffect(() => { const todo = todoRef.current; if (!todo) return; let lastScrollTop = 0; function scrollDetection() { // 注意:DOM元素的scrollTop是属性,不是方法 const st = todo.scrollTop; if (st > lastScrollTop) { console.log("GOING DOWN"); } else { console.log("GOING UP"); } lastScrollTop = st; } todo.addEventListener("scroll", scrollDetection); // 组件卸载时移除监听,避免内存泄漏 return () => todo.removeEventListener("scroll", scrollDetection); }, []); // 绑定ref到目标元素 <div className="todo" ref={todoRef}> {/* 子组件内容 */} </div>
同时注意:原代码中this.scrollTop()是错误写法,DOM元素的scrollTop是属性,需改为todo.scrollTop。
2. for 属性警告
在React的JSX语法中,不能直接使用HTML的for属性(因为for是JavaScript关键字),React提供htmlFor作为替代。例如原代码中的<label for="inputId">需改为<label htmlFor="inputId">,即可消除该警告。
3. 页面空白的根源
第一个错误会中断JavaScript执行,导致后续渲染逻辑无法完成,最终页面显示空白。修复空指针错误后,页面即可正常渲染。
内容的提问来源于stack exchange,提问作者Javi Gauxachs Monserrat

