I'm having problem setting state. I've to pass extra classes to CardComponent
on click, on click is working fine, setState
is called, and the callback
executes, but state is not mutated (as logs clearly deny that state is updated - see onSelect
below). How could I fix that?
Flow is that if an item is selected, parent component resets the array with selected property set on each item (the selected result object gets selected
set to true
), that works fine and list is reset, selected is highlighted. Then if user clicks on another item (SearchResult component), it should update itself and apply extra classes. This time it's guarenteed that parent would not reset the list.
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>
);
}
}