【问题标题】:Why is my React app completely reloading after a state change? [duplicate]为什么我的 React 应用程序在状态更改后完全重新加载? [复制]
【发布时间】:2019-11-08 08:52:23
【问题描述】:

我对 React 很陌生,如果这是一个愚蠢的问题,我深表歉意,我怀疑是这样。

我有一个带有下拉列表、按钮和列表的简单 React 应用程序。单击按钮时,下拉列表中的选定项目将添加到列表中。添加到列表中的每个项目也有一个与之关联的删除按钮。

我需要 SelectComponent(下拉菜单和按钮)和 ListComponent(列表和按钮)来了解列表中的项目是什么,以便他们可以从中添加/删除项目,因此我将状态存储在父 App 组件中并将它作为道具传递给孩子,以及可以更新它的回调函数(使用setState())。这是我所拥有的:

选择组件

class SelectComponent extends Component<SelectProps, {}> {
  constructor(props: any) {
    super(props);
    this.changeHandler = this.changeHandler.bind(this);
    this.clickHandler = this.clickHandler.bind(this);
  }

  changeHandler(event: ChangeEvent<HTMLSelectElement>) {
    currentSelection = event.target.value;
  }

  clickHandler(event: MouseEvent<HTMLButtonElement>) {
    this.props.selectedItems.push(currentSelection);
    this.props.updateList(this.props.selectedItems);
  }

  render() {
    let optionItems = this.props.options.map((optionItem, index) =>
        <option>{optionItem}</option>
      );

    return (
      <form>
        <div>
          <select onChange={this.changeHandler}>
            <option selected disabled hidden></option>
            {optionItems}
          </select>
          <br />
          <button type="submit" onClick={this.clickHandler}>Add to list</button>
        </div>
      </form>
    );
  }
}

列表组件

class ListComponent extends Component<ListProps, {}> {
  constructor(props: any) {
    super(props);
    this.removeListItem = this.removeListItem.bind(this);
  }

  removeListItem(i: number) {
    this.props.selectedItems.filter((selection, j) => i !== j);
    this.props.updateList(this.props.selectedItems);
  }

  render() {
    let listItems;

    if (this.props.selectedItems) {
      listItems = this.props.selectedItems.map((listItem, index) =>
        <li>{listItem}<button onClick={() => this.removeListItem(index)}>Delete</button></li>
      );
    }

    return (
      <div>
        <ul>
          {listItems}
        </ul>
      </div>
    );
  }
}

主应用

class App extends Component<{}, State> {
  constructor(props: any) {
    super(props);
    this.state = {
      selectedItems: []
    }
    this.updateList = this.updateList.bind(this);
  }

  updateList(selectedItems: string[]) {
    this.setState({selectedItems});
  }

  render() {
    return (
      <div>
        <SelectComponent options={["Cyan", "Magenta", "Yellow", "Black"]} selectedItems={this.state.selectedItems} updateList={this.updateList} />
        <ListComponent selectedItems={this.state.selectedItems} updateList={this.updateList} />
      </div>
    );
  }
}

我还有几个定义 props 和 state 的接口,以及一个用于保存下拉列表中当前选定项目的变量。

我想要发生的是:按下“添加到列表”按钮,将当前下拉选择添加到道具,然后将道具传递给父类中的updateList() 函数,更新状态。然后父类应该根据新状态重新渲染自己和子组件。从我通过查看控制台可以看出,这确实发生了。

但是,由于某种原因,在完成 ListComponent 渲染后,应用程序会完全重新加载,清除状态和列表,并将下拉列表恢复为默认值。我可以说出来,因为我在调用 ListComponent 渲染函数后立即在控制台中看到了Navigated to http://localhost:3000/?

那么我做错了什么?再说一次,我对 React 还是很陌生,所以我觉得这很简单,我很想念。任何帮助将不胜感激!

编辑:忘记提及(尽管可能很明显)我正在使用 TypeScript 进行编码,尽管我认为这与问题无关。

【问题讨论】:

标签: javascript html reactjs typescript


【解决方案1】:

如果您正在使用formsubmit 处理程序,那么您必须在提交方法中设置event.preventDefault()

你必须在clickHandler方法中设置preventDefault()

  clickHandler(event) {
    event.preventDefault(); // set it...
    this.props.selectedItems.push(currentSelection);
    this.props.updateList(this.props.selectedItems);
  }

【讨论】:

【解决方案2】:

因为您使用的是表单和按钮类型提交。键入 submit 是您的应用重新加载的原因。 为了防止应用默认重新加载,在Select ComponentclickHandler函数中,在函数顶部添加preventDefault

event.preventDefault();

【讨论】:

  • 呃,当然,我知道我忘记了什么。这似乎已经停止了重新加载。看起来我还有其他问题要解决,但这是最重要的问题。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
  • 2021-12-11
  • 2021-12-13
  • 2019-03-04
  • 2018-11-06
相关资源
最近更新 更多