React JS单文件创建多组件报错:Uncaught TypeError问题求助
解决React多组件中的"Super expression must either be null or a function"错误
作为React新手碰到这个问题太正常啦,我刚学的时候也踩过类似的坑。这个错误大概率是组件继承写法不对或者React/ReactDOM的引入环节出了问题,咱们一步步拆解原因和解决办法:
常见原因1:组件继承写错了
类组件必须继承React.Component(或者React.PureComponent),如果漏写了React.前缀,或者拼写错误,就会导致继承的"父类"是undefined,触发这个错误。
错误写法:
class MyComponent extends Component { // 这里没加React.,Component是undefined render() { return <div>Hello</div>; } }
正确写法二选一:
// 写法1:直接写全路径 class MyComponent extends React.Component { render() { return <div>Hello</div>; } } // 写法2:先解构,再用简写 const { Component } = React; class MyComponent extends Component { render() { return <div>Hello</div>; } }
常见原因2:CDN引入顺序或版本不对
用CDN方式引入React时,顺序和版本匹配很关键:必须先引React,再引ReactDOM,最后加Babel转译JSX。而且要确保用的是开发版(带.development.js)方便调试,生产环境再换压缩版。
正确的HTML引入示例:
<!-- React核心库 --> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <!-- ReactDOM渲染库 --> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <!-- Babel转译JSX --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <!-- 你的React代码必须放在type="text/babel"的script标签里 --> <script type="text/babel"> // 这里写你的多组件代码 </script>
另外注意React 18和旧版本的渲染写法不一样:
- React 18用
createRoot:
const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
- React 16及之前用
ReactDOM.render:
ReactDOM.render(<App />, document.getElementById('root'));
常见原因3:函数组件错误用了class写法
如果是写函数组件,千万别加class关键字,直接写函数就行:
错误写法(把函数组件写成类了):
class MyFunctionComponent { // 没有继承React.Component,直接报错 return <div>Hi</div>; }
正确的函数组件写法:
// 普通函数写法 function MyFunctionComponent() { return <div>Hi</div>; } // 箭头函数写法 const MyFunctionComponent = () => { return <div>Hi</div>; };
结合你的代码片段排查
看你提供的代码里有表单提交逻辑onFormSubmit,如果这个方法是类组件里的,还要记得绑定this(比如在构造函数里绑定,或者用箭头函数定义方法),不然也可能衍生其他错误。
给你一个完整的单文件多组件正确示例,你可以对照着改自己的代码:
<!DOCTYPE html> <html> <head> <title>React多组件示例</title> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> // 列表组件 class TodoList extends React.Component { render() { return ( <ul> {this.props.items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); } } // 表单组件 class TodoForm extends React.Component { constructor(props) { super(props); this.state = { inputValue: '' }; // 绑定方法的this this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); } handleChange(e) { this.setState({ inputValue: e.target.value }); } handleSubmit(e) { e.preventDefault(); if (this.state.inputValue.trim()) { this.props.onAddItem(this.state.inputValue); this.setState({ inputValue: '' }); } } render() { return ( <form onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} placeholder="输入内容..." /> <button type="submit">添加</button> </form> ); } } // 父组件 class App extends React.Component { constructor(props) { super(props); this.state = { items: ['hello'] }; this.addItem = this.addItem.bind(this); } addItem(newItem) { this.setState(prevState => ({ items: [...prevState.items, newItem] })); } render() { return ( <div> <h2>我的列表</h2> <TodoForm onAddItem={this.addItem} /> <TodoList items={this.state.items} /> </div> ); } } // 渲染根组件 const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Seshamany Vigneshan
相关产品推荐
相关产品推荐

