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

React中<ul>电影列表不显示+受控输入警告及仅展示收藏电影需求

解决你的React电影列表问题(受控输入警告+列表不显示+收藏过滤)

咱们一步一步来拆解并解决你遇到的问题:

1. 先搞定「受控/非受控输入」的警告

这个警告的根源很明确:你的文本输入框和收藏复选框绑定的movieName、favorite,在组件初始的state里根本没定义!一开始React认为这些输入是非受控的,等你输入内容触发setState后,这两个变量突然被赋值,组件就切换成了受控模式,所以触发了警告。

修正方法:在组件的constructor里初始化这两个状态:

constructor(props) {
  super(props);
  this.state = {
    movieName: '', // 初始化电影名称输入框的受控值
    favorite: false, // 初始化收藏复选框的受控状态
    list: [],
    showList: false // 新增状态:控制列表是否显示
  };
  // 方法绑定保持不变
  this.handleChange = this.handleChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);
  this.addMovie = this.addMovie.bind(this);
}

2. 让电影列表显示出来,并且只展示收藏的电影

现在你的代码有两个核心问题导致列表看不到:

  • addMovie方法存的是没用的value变量,根本没把输入的电影名称和收藏状态存入列表
  • 点击按钮调用listMovies只是返回了JSX,但没有把它渲染到页面上

修正addMovie方法:存储电影的完整信息

我们需要把电影名称和是否收藏作为一个对象存入列表,这样后续才能过滤出收藏的电影:

addMovie() {
  // 用prevState确保拿到最新的状态(因为setState是异步操作)
  this.setState(prevState => ({
    list: [...prevState.list, {
      name: prevState.movieName,
      isFavorite: prevState.favorite
    }],
    movieName: '', // 提交后清空输入框
    favorite: false // 提交后重置复选框
  }));
}

让列表能被渲染到页面上

删掉原来的listMovies方法,改成用showList状态控制列表的显示/隐藏:
在render方法里,把按钮和列表部分改成这样:

<button onClick={() => this.setState(prevState => ({ showList: !prevState.showList }))}>
  {this.state.showList ? 'Hide Movies' : 'List Movies'}
</button>

{/* 当showList为true时,渲染只包含收藏电影的列表 */}
{this.state.showList && (
  <ul>
    {this.state.list
      .filter(movie => movie.isFavorite) // 过滤出标记为收藏的电影
      .map((movie, index) => (
        <li key={index}>{movie.name}</li>
      ))}
  </ul>
)}

完整的修正后代码

class Movie extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      movieName: '',
      favorite: false,
      list: [],
      showList: false
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.addMovie = this.addMovie.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({ [name]: value });
  }

  handleSubmit(event) {
    event.preventDefault();
    this.addMovie();
  }

  addMovie() {
    this.setState(prevState => ({
      list: [...prevState.list, {
        name: prevState.movieName,
        isFavorite: prevState.favorite
      }],
      movieName: '',
      favorite: false
    }));
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>
            Movie name:
            <input name="movieName" type="text" value={this.state.movieName} onChange={this.handleChange} />
            Favorite?
            <input name="favorite" type="checkbox" checked={this.state.favorite} onChange={this.handleChange} />
          </label>
          <input type="submit" value="Submit" />
        </form>
        <button onClick={() => this.setState(prevState => ({ showList: !prevState.showList }))}>
          {this.state.showList ? 'Hide Movies' : 'List Movies'}
        </button>
        {this.state.showList && (
          <ul>
            {this.state.list
              .filter(movie => movie.isFavorite)
              .map((movie, index) => (
                <li key={index}>{movie.name}</li>
              ))}
          </ul>
        )}
      </div>
    );
  }
}

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

现在你再运行代码:

  • 不会再有受控/非受控输入的警告
  • 提交电影后,点击「List Movies」按钮就能看到所有标记为收藏的电影
  • 再次点击按钮可以隐藏列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:35:46