Reputation: 68780
Newbie question.
I'm learning ReactJS in Typescript and am coming from an AngularJS background (trying to unlearn AngularJS).
The code below runs and displays the props.compiler
. When I tap the H1
, the handler
fires but the React code doesn't update the display like it would in AngularJS
.
What am I missing?
export interface IHelloProps {
compiler: string;
framework: string;
}
export class Hello extends React.Component<IHelloProps> {
constructor(props: IHelloProps) {
super(props);
this.x = props.compiler;
}
private x: string;
get Name(): string {
return this.x;
}
set Name(value: string) {
this.x = value;
}
render() {
return <h1 onClick={this.handler}>Hello from {this.Name}!</h1>;
}
handler = async (t: any) => {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
this.Name = data.current_user_url;
};
}
Upvotes: 1
Views: 666
Reputation: 42556
TypeScript's interface is purely for typechecking. You should not be directly referencing any of its properties.
Instead, I would recommend you to create an interface for your state, which holds the values of current_user_url
from your fetch
request.
Then, on your click handler, you update the state by calling setState() to re-render the component with the updated state. On important thing to take note, is that you should never mutate state directly.
In order to fully implement TypeScript's typechecking capabilities on your component, you should use provide React.Component
with its prop and state type parameters.
I have modified your code such that your component is TypeScript-compliant. Do take note of the new IHelloState
interface.
export interface IHelloProps {
compiler: string;
framework: string;
}
export interface IHelloState {
name: string;
}
export class Hello extends React.Component<IHelloProps, IHelloState> {
constructor(props: IHelloProps) {
super(props);
this.state = {
name: '',
};
}
handler = async (t: React.MouseEvent<HTMLButtonElement>)=> {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
this.setState({
name: data.current_user_url,
});
}
render() {
const { name } = this.state;
return <h1 onClick={this.handler}>
Hello from {name}
</h1>;
}
}
You may read more about working with React and TypeScript over here.
Upvotes: 1
Reputation: 53934
There is no two-way binding like in AngularJS, you need to use setState
in order to schedule an update to a component’s state object:
// A bit more React-Class oriented example
class App extends React.Component {
state = {
currentUser: this.props.compiler
};
handler = async t => {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
this.setState({ currentUser: data.current_user_url });
};
render = () => {
const { currentUser } = this.state;
return <h1 onClick={this.handler}>Hello from {currentUser}!</h1>;
};
}
// Original OP class
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
x: props.compiler
};
}
get Name() {
return this.state.x;
}
set Name(value) {
this.setState({ x: value });
}
handler = async t => {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
this.setState({ x: data.current_user_url });
};
render = () => {
return <h1 onClick={this.handler}>Hello from {this.Name}!</h1>;
};
}
Try reading the Getting Started section which explains it in depth.
Upvotes: 3
Reputation: 522
In React you don't set the values like you did in your setter function.
React renders the DOM asynchronously by comparing the virtual DOM.
So you need to use setState() to update the state of your DOM.
You can add state in your code and pass it to the React component.
handler = async (t: any)=> {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
this.Name=data.current_user_url;
this.setState({name:data.current_user_url}); //name being the state variable
}
Hope it helps!!
Upvotes: 2