React状态在回调函数内部无法更新

4

我在设置状态时遇到了问题。我需要在单击事件中传递额外的类到CardComponent,单击事件正常工作,setState被调用,并且callback执行,但状态没有改变(如下面的onSelect所示,日志明确拒绝了状态已更新)。我该如何解决这个问题?

流程是,如果选择一个项目,父组件将重置带有每个项目上设置为选定属性的数组(选定结果对象的selected设置为true),这样可以正常工作并且列表会重置,选定会突出显示。然后,如果用户单击另一个项目(SearchResult组件),它应该更新自身并应用额外的类。这次保证父级不会重置列表。

import { Component, ReactNode } from "react";
import { Subject, Subscription } from "rxjs";
import CardComponent from "../../utils/card.component";

export interface SearchResultComponentClickEvent {
  (_id: string): void;
}

export interface SearchResultComponentProps {
  result: any;
  full: boolean;
  onClick: SearchResultComponentClickEvent;
  onSelect: Subject<string>;
}

interface SearchResultComponentState {
  selected: string;
  extraClasses: string;
}

export default class SearchResult extends Component<
  SearchResultComponentProps,
  SearchResultComponentState
> {
  onSelectSubscription: Subscription = null;

  constructor(props: SearchResultComponentProps) {
    super(props);
    let extraClasses = "mb-4";
    if (this.props.result.selected) extraClasses += " border border-primary";

    this.state = {
      selected: this.props.result.selected,
      extraClasses,
    };

    this.onSelect = this.onSelect.bind(this);
  }

  componentDidMount(): void {
    this.onSelectSubscription = this.props.onSelect.subscribe((_id: string) => {
      this.setState({
        selected: '',
        extraClasses: 'mb-4'
      });
    });
  }

  componentWillUnmount(): void {
    this.onSelectSubscription.unsubscribe();
  }

  onSelect() {
    this.setState({
      selected: this.props.result._id,
      extraClasses: "mb-4 border border-primary",
    }, () => {
      console.log(this.state);
      // logs: { selected: '', extraClasses: "mb4 " }
    });

    this.props.onClick(this.props.result._id);
  }

  view(): ReactNode {
    return <div>Simple view</div>
  }

  fullView(): ReactNode {
    return <div>Extended view</div>;
  }

  render(): ReactNode {
    return (
      <CardComponent
        padding={0}
        onClick={this.onSelect}
        extraClasses={this.state.extraClasses}
        key={this.state.extraClasses}
      >
        {this.props.full ? this.fullView() : this.view()}
      </CardComponent>
    );
  }
}

CardComponent组件长什么样子?即它如何使用extraClasses属性? - Brendan Bond
2个回答

0

您已更改状态,但setState是异步的,更改状态不会立即给出其更新后的值https://facebook.github.io/react/docs/react-component.html#setstate。如果您可以展示一下CardComponent中您正在做什么的片段,可以提供更可靠的解决方案。 如果您仍然想采用这种方法,可以将您的onSelect更改为以下内容。

onSelect() {
    this.setState({
      selected: this.props.result._id,
      extraClasses: "mb-4 border border-primary",
    }, function() { 
         console.log(this.state);
         this.props.onClick(this.props.result._id);
       });
  } 

这将包装或附加一个回调到状态中,保证它,但它有自己的副作用。 我还建议使用componentDidUpdate而不是这个解决方案,更精确。


0
问题可能出在rxjs Subscription对象中。插入console.log并检查...
componentDidMount(): void {
  this.onSelectSubscription = this.props.onSelect.subscribe((_id: string) => {
    // Log
    console.log('componentDidMount-onSelectSubscription', this.state);

    this.setState({
      selected: '',
      extraClasses: 'mb-4'
    });
  });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接