You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TodoList组件引入自定义<List>子组件后页面无法渲染问题求助

嘿,我发现你遇到的问题根源很明确——是组件引用的方式出错啦!

问题核心原因

你在TodoList类内部定义了List这个子组件,但在render方法里直接写<List items={this.state.items}/>,JavaScript会把List当成全局变量查找,根本找不到它(因为它是挂在TodoList实例上的类属性),直接导致组件渲染报错,页面就变成空白了。

另外还有几个小细节可以优化,顺便帮你一起修正了:

修正后的完整可运行代码

class TodoList extends React.Component {
  // 把List作为类属性定义没问题,但要记得用this调用
  List = (props) => (
    <ul>
      {props.items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );

  state = {
    term: '',
    items: []
  };

  onChange = (event) => {
    this.setState({ term: event.target.value });
  };

  onSubmit = (event) => {
    event.preventDefault();
    // 用函数式更新this.state更安全,避免状态依赖问题
    this.setState(prevState => ({
      term: '',
      items: [...prevState.items, prevState.term]
    }));
  };

  render() {
    // 关键修正:这里必须用this.List来引用类内部的子组件
    return (
      <>
        <div>
          <h2>Todo List</h2>
          <form className="App" onSubmit={this.onSubmit}>
            <input value={this.state.term} onChange={this.onChange} />
            <button>Submit</button>
          </form>
          {/* 这里改成this.List就正常了 */}
          <this.List items={this.state.items} />
        </div>
        <style>{`
          .is-done {
            text-decoration: line-through;
          }
        `}</style>
      </>
    );
  }
}

// 别忘了把组件挂载到页面的DOM元素上(比如id为root的div)
ReactDOM.render(<TodoList />, document.getElementById('root'));

更推荐的优化方案

其实把子组件定义在类外面会更合理,既不用纠结this的引用问题,性能也更好(不会每次父组件渲染都重新创建子组件):

// 把List组件移到TodoList类外部
const List = (props) => (
  <ul>
    {props.items.map((item, index) => (
      <li key={index}>{item}</li>
    ))}
  </ul>
);

class TodoList extends React.Component {
  // ... 其他代码和之前一样
  render() {
    // 现在直接用<List />就可以了
    return (
      <>
        <div>
          <h2>Todo List</h2>
          <form className="App" onSubmit={this.onSubmit}>
            <input value={this.state.term} onChange={this.onChange} />
            <button>Submit</button>
          </form>
          <List items={this.state.items} />
        </div>
        <style>{`
          .is-done {
            text-decoration: line-through;
          }
        `}</style>
      </>
    );
  }
}

ReactDOM.render(<TodoList />, document.getElementById('root'));

额外的功能优化建议

既然你写了.is-done的样式,不如顺便实现待办项的完成状态切换功能,让你的TodoList更实用:

  1. 给每个待办项添加唯一ID和完成状态字段
  2. 实现点击切换完成状态的方法
  3. 绑定样式到完成的项

代码示例:

const List = (props) => (
  <ul>
    {props.items.map((item) => (
      <li 
        key={item.id} 
        className={item.done ? 'is-done' : ''}
        onClick={() => props.toggleDone(item.id)}
      >
        {item.text}
      </li>
    ))}
  </ul>
);

class TodoList extends React.Component {
  state = {
    term: '',
    items: []
  };

  onChange = (event) => {
    this.setState({ term: event.target.value });
  };

  onSubmit = (event) => {
    event.preventDefault();
    if (!this.state.term.trim()) return; // 避免添加空项
    this.setState(prevState => ({
      term: '',
      items: [...prevState.items, { 
        id: Date.now(), 
        text: prevState.term, 
        done: false 
      }]
    }));
  };

  toggleDone = (itemId) => {
    this.setState(prevState => ({
      items: prevState.items.map(item => 
        item.id === itemId ? {...item, done: !item.done} : item
      )
    }));
  };

  render() {
    return (
      <>
        <div>
          <h2>Todo List</h2>
          <form className="App" onSubmit={this.onSubmit}>
            <input value={this.state.term} onChange={this.onChange} placeholder="添加待办项..." />
            <button>Submit</button>
          </form>
          <List items={this.state.items} toggleDone={this.toggleDone} />
        </div>
        <style>{`
          .is-done {
            text-decoration: line-through;
            color: #999;
          }
          li {
            cursor: pointer;
            margin: 8px 0;
          }
        `}</style>
      </>
    );
  }
}

ReactDOM.render(<TodoList />, document.getElementById('root'));

内容的提问来源于stack exchange,提问作者rohit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:17:48