Skip to content

Instantly share code, notes, and snippets.

@behnood-eghbali
Last active March 31, 2021 15:20
Show Gist options
  • Save behnood-eghbali/1f79cee83d22b9614f342c6eaf83224d to your computer and use it in GitHub Desktop.
Save behnood-eghbali/1f79cee83d22b9614f342c6eaf83224d to your computer and use it in GitHub Desktop.
React + TypeScript code samples with error/bug fixes
import React, {Component} from 'react';
// import { createBrowserHistory } from 'history';
import Chats from './Chats';
import Contacts from './Contacts';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
/* Error: Property 'path' is missing in type '{}' but required in type 'Readonly<Props>'. TS2741
Error: Type 'Props' is not assignable to type 'string'.ts(2322)
Contacts.tsx: The expected type comes from property 'path' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Contacts> & Readonly<Props> & Readonly<{ children?: ReactNode; }>' */
interface Props {
path?: string;
}
interface Contact {
name: string;
number: string;
}
interface State {
newContact: Contact;
contacts: Contact[];
buttonClicked: boolean;
value: string;
//handleChange(event: Event): void;
}
// const history = createBrowserHistory();
export default class App extends Component<Props, State> {
state = {
newContact: { name: '', number: ''},
contacts: [],
buttonClicked: false,
value: ''
//handleChange(event: Event){}
};
/* Error: Property 'setState' does not exist on type 'App'.ts(2339)
https://github.com/microsoft/TypeScript/issues/31595
handleChange = () => {this.setState({
contacts: [...this.state.contacts, this.state.newContact]
})
} */
/* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts
setState<K extends keyof S>(
state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
callback?: () => void
): void; */
/* setState<T extends State>(state: T) {
return state;
} */
/* setState(state: State) {
return state;
} */
/* Error: Argument of type '{ this: any; }' is not assignable to parameter of type 'State'.
Object literal may only specify known properties, and 'this' does not exist in type 'State'.ts(2345) */
/* Error: Argument of type '{ value: any; }' is not assignable to parameter of type 'State'.
Type '{ value: any; }' is missing the following properties from type 'State': newContact, contacts.ts(2345) */
handleNameChange = (event: React.FormEvent<HTMLInputElement>) => {
this.setState({
newContact: {
name: event.currentTarget.value,
number: this.state.newContact.number
}
});
}
handleNumberChange = (event: React.FormEvent<HTMLInputElement>) => {
this.setState({
newContact: {
name: this.state.newContact.name,
number: event.currentTarget.value
}
});
}
handleAddContact = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
this.setState({
contacts: [...this.state.contacts, this.state.newContact]
});
}
//handleChange (event: React.FormEvent<HTMLInputElement>) => void
//handleChange = (event: React.FormEvent<HTMLInputElement>) => void
/* handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
alert(event.currentTarget.tagName);
}; */
contactsRef = React.createRef<Contacts>();
componentDidMount() {
console.log(this.contactsRef.current);
}
render() {
const {path} = this.props;
return (
<div className="MyApp">
<header className="MyApp-header">
<h2 className="MyApp-title">React Messaging App</h2>
</header>
<div className="row">
<div className="col-md-1 col-lg-1"/>
<div className="col-md-10 col-lg-10">
<div className="jumbotron shadow-lg">
<ul className="nav flex-column">
<li className="nav-item">
<h6>Search Contact</h6>
<div className="btn-group-vertical shadow">
<input type="text" className="form-control" placeholder="Contact Name" />
</div>
</li>
<li className="nav-item">
<h6>Chats</h6>
<div className="btn-group-vertical shadow">
{/* <Chats data={???} /> */}
</div>
</li>
<li className="nav-item">
<h6>Contacts</h6>
<div className="btn-group-vertical shadow">
<Contacts path={path} ref={this.contactsRef} />
<button type="button" className="btn btn-light">New Contact</button>
</div>
</li>
<li className="nav-item">
<h6>New Contact</h6>
<form>
<div className="btn-group-vertical form-group shadow">
<input type="text" value={this.state.newContact.name} className="form-control" onChange={this.handleNameChange} placeholder="Name" required/>
<input type="text" value={this.state.newContact.number} className="form-control" onChange={this.handleNumberChange} placeholder="Phone Number" required/>
<button type="submit" value="Submit" className="btn btn-dark" onClick={this.handleAddContact}>Add Contact</button>
</div>
</form>
</li>
</ul>
{/* <input type="text" onChange={this.handleChange} /> */}
{/* <button onClick={this.handleClick}>click me!</button> */}
<pre>{JSON.stringify(this.state, null, 2)}</pre>
</div>
</div>
<div className="col-md-1 col-lg-1"/>
</div>
</div>
);
}
}
import React, { Component } from 'react';
import { createBrowserHistory } from 'history';
interface Props {
path?: string;
data: [];
}
interface State {
value: string;
}
const history = createBrowserHistory();
let componentUrl = 'http://localhost:3000/chats',
chatsUrl = new URL(componentUrl);
console.log(chatsUrl);
let dataUrl = 'http://localhost:3001/chats',
chatsDataUrl = new URL(dataUrl);
console.log(chatsDataUrl);
export default class Chats extends Component<Props, State> {
state = {
value: 'Chats'
};
unlisten: any;
data = [];
componentDidMount() {
fetch(chatsDataUrl.href)
.then(res => res.json())
.then(data => {
this.props.data.map((item: any, index: any) => {
return (
<div key={index}>
<h2>{item.id}</h2>
<h2>{item.message}</h2>
</div>
)
})
console.log(data);
})
/* this.unlisten = history.listen(() => {
this.handleChats(undefined);
}); */
}
/* componentWillUnmount() {
this.unlisten();
} */
handleChats = (event: React.MouseEvent<HTMLAnchorElement> | undefined) => {
history.push(chatsUrl.pathname, {});
this.setState({value: this.state.value});
console.log(this.state.value, history.location.pathname);
};
render() {
return (
<a className="btn btn-light chats" role="button" href={this.props.path} onClick={this.handleChats}>{this.state.value}</a>
);
}
}
import React, { Component } from 'react';
import { createBrowserHistory } from 'history';
interface Props {
path?: string;
}
interface State {
value: string;
}
const history = createBrowserHistory();
// let contactsUrl = '/contacts';
// let contactsDataUrl = 'http://localhost:3001/contacts';
// const pathname = this.state.currentUrl.pathname;
/* Error: Property 'pathname' does not exist on type 'string'.ts(2339)
https://url.spec.whatwg.org/#api
https://developer.mozilla.org/en-US/docs/Web/API/URL */
let componentUrl = 'http://localhost:3000/contacts',
contactsUrl = new URL(componentUrl);
console.log(contactsUrl);
export default class Contacts extends Component<Props, State> {
state = {
value: 'Contacts'
};
handleContacts = (event: React.MouseEvent<HTMLAnchorElement>) => {
history.push(contactsUrl.pathname, {});
this.setState({value: this.state.value});
console.log(this.state.value, history.location.pathname);
};
render() {
if(history.location.pathname === contactsUrl.pathname) {
console.log('loading contacts...');
}
return (
<a className="btn btn-light contacts" role="button" href={this.props.path} onClick={this.handleContacts}>{this.state.value}</a>
);
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
/* Error: JSX element type 'App' is not a constructor function for JSX elements.
Type 'App' is missing the following properties from type 'ElementClass': context, forceUpdate, props, state, refs ts(2605)
ReactDOM.render(<App />, document.getElementById('root')); */
/* ReactDOM.render(
React.createElement(App, null),
document.getElementById('root')
); */
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.register();
{
"name": "my-app-ts",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "24.0.13",
"@types/node": "^12.0.2",
"@types/react": "^16.8.18",
"@types/react-dom": "^16.8.4",
"bootstrap": "^4.3.1",
"history": "^4.9.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"typescript": "3.4.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"noImplicitAny": false
},
"include": [
"src"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment