I am creating a component in React using tsx that uses an interface as its props. Like shown below:
export interface ISummaryStats {
firstName: string,
lastName: string,
}
export class TestComponent extends React.Component<ISummaryStats> {
refreshData = async () => {
const data = await this.getData();
this.props.firstName = data;
};
getData = async () => {
//Call the API to get the data
//! API call goes here
return 'Jimmy';
}
public render(): React.ReactNode {
return (
<div>
<h1>
{this.props.firstName}
</h1>
<h2>
{this.props.lastName}
</h2>
<button onClick={this.refreshData}>Click me</button>
</div>
);
}
}
What I am trying to do is create a button that calls my API to see if there has been any changes to the data. If so, I want to update the display. However, with the current code I get the following error: Cannot assign to 'firstName' because it is a read-only property.
I am not that experience with interfaces, should I be storing the props values in an object when the component loads so that I can modify that instead of trying to modify the props or is there a different method?
CodePudding user response:
In React, properties are read only. Use state
and setState
to allow changing values, as outlined in the docs: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class
setState
triggers a rerender of the component, updating the UI. That's the reason for this pattern.
When using typescript, the first generic type is the type of properties, the second is the type of state.
export interface ISummaryStats {
firstName: string;
lastName: string;
}
export class TestComponent extends React.Component<
ISummaryStats, // type of props
ISummaryStats // type of state
> {
constructor(props) {
super(props);
this.state = props;
}
refreshData = async () => {
const data = await this.getData();
this.setState({ firstName: data });
};
getData = async () => {
return 'Jimmy';
};
public render(): React.ReactNode {
return (
<div>
<h1>{this.state.firstName}</h1>
<h2>{this.state.lastName}</h2>
<button onClick={this.refreshData}>Click me</button>
</div>
);
}
}
Stackblitz: https://stackblitz.com/edit/react-ts-8htues?file=App.tsx