sort conflict
This commit is contained in:
parent
506aecf4d5
commit
ce3c352ce6
2 changed files with 0 additions and 208 deletions
102
zk/Events.md
102
zk/Events.md
|
@ -1,102 +0,0 @@
|
|||
---
|
||||
tags:
|
||||
- typescript
|
||||
- react
|
||||
---
|
||||
|
||||
# Events
|
||||
|
||||
Building on the previous examples for React TypeScript we are going to add a
|
||||
simple form that enables the user to add people to the list. This will
|
||||
demonstrate how we type components that use event handlers.
|
||||
|
||||
We are going to use the preexisting interface for recording the list items:
|
||||
|
||||
```tsx
|
||||
interface IState {
|
||||
people: {
|
||||
name: string;
|
||||
age: number;
|
||||
}[];
|
||||
}
|
||||
```
|
||||
|
||||
Our form:
|
||||
|
||||
```ts
|
||||
import {IState as Props};
|
||||
```
|
||||
|
||||
```tsx
|
||||
|
||||
interface IProps {
|
||||
people: Props["people"]
|
||||
setPeople: React.Dispatch<React.SetStateAction<Props["people"]>>
|
||||
}
|
||||
|
||||
const AddToList = () => {
|
||||
const [people, setPeople] = useState<IState["people"]>({})
|
||||
const [formVals, setFormVals] = useState({});
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
setFormValues({
|
||||
...input,
|
||||
[e.target.name]: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleClick = (): void => {
|
||||
if (!input.name || !input.age) return
|
||||
|
||||
setPeople({
|
||||
...people,
|
||||
{
|
||||
name: input.name,
|
||||
age: input.age
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input type="text" name="name" value={input.name} onChange={handleChange} />
|
||||
<input type="text" name="age" value={input.age} onChange={handleChange} />
|
||||
</form>
|
||||
<button onClick={handleClick}>Add to list</button>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
This follows standard practise for
|
||||
[controlled-components](Forms.md). The TS
|
||||
specific additions:
|
||||
|
||||
- We define the change event as being of the type `React.ChangeEvent` and state
|
||||
that it corresponds to a generic - `HTMLInputElement`. So we are saying that
|
||||
whenever this function is called we must be passing it an input element so
|
||||
that we can extract the event associated with its `target` property.
|
||||
|
||||
- We are passing around variations on the `IState` interface in order to type
|
||||
the values that we are adding to the people array.
|
||||
|
||||
## Further standard types for event handling
|
||||
|
||||
### onClick
|
||||
|
||||
```tsx
|
||||
handleClick(event: MouseEvent<HTMLButtonElement>) {
|
||||
event.preventDefault();
|
||||
alert(event.currentTarget.tagName);
|
||||
}
|
||||
```
|
||||
|
||||
### onSubmit
|
||||
|
||||
```tsx
|
||||
handleSubmit(e: React.SyntheticEvent) {
|
||||
event.preventDefault();
|
||||
}
|
||||
```
|
||||
|
||||
> Most event types and their associated generics will be revealed by VS Code
|
||||
> Intellisense so you don't need to memorize them all
|
106
zk/events.md
106
zk/events.md
|
@ -1,106 +0,0 @@
|
|||
---
|
||||
id: events
|
||||
aliases: []
|
||||
tags:
|
||||
- backend
|
||||
- node-js
|
||||
---
|
||||
|
||||
# Node.js `events` module
|
||||
|
||||
In most cases you won't interact with the `events` module directly since other
|
||||
modules and third-party modules are abstractions on top of it. For instance the
|
||||
`http` module is using events under the hood to handle requests and responses.
|
||||
|
||||
Another way of putting this is to say that all events in Node inherit from the
|
||||
`EventEmitter` constructor, which is the class you instantiate to create a new
|
||||
event. At bottom everything in Node is an event with a callback, created via
|
||||
event emitters.
|
||||
|
||||
Because Node's runtime is [event-driven](Event_loop.md), it is event-emitter
|
||||
cycles that are being processed by the Event Loop, although you may know them as
|
||||
`fs` or `http` (etc) events. The call stack that the Event Loop works through is
|
||||
just a series of event emissions and their associated callbacks.
|
||||
|
||||
## Event Emitters
|
||||
|
||||
- All objects that emit events are instances of the `EventEmitter` class. This
|
||||
object exposes an `eventEmitter.on()` function that allows one or more
|
||||
functions to be attached to named events emitted by the object.
|
||||
- These functions are **listeners** of the emitter.
|
||||
|
||||
## Basic syntax
|
||||
|
||||
```js
|
||||
const EventEmitter = require("events"); // import the module
|
||||
|
||||
// Raise an event
|
||||
const emitter = new EventEmitter("messageLogged");
|
||||
|
||||
// Register a listener
|
||||
emitter.on("messagedLogged", function () {
|
||||
console.log("The listener was called.");
|
||||
});
|
||||
```
|
||||
|
||||
- If we ran this file, we would see `The listener was called` logged to the
|
||||
console.
|
||||
- Without a listener (similar to a subscriber in Angular) nothing happens.
|
||||
- When the emission occurs the emitter works _synchronously_ through each
|
||||
listener function that is attached to it.
|
||||
|
||||
## Event arguments
|
||||
|
||||
- Typically we would not just emit a string, we would attach an object to the
|
||||
emitter to pass more useful data. This data is called an **Event Argument**.
|
||||
- Refactoring the previous example:
|
||||
|
||||
```js
|
||||
// Raise an event
|
||||
const emitter = new EventEmitter("messageLogged", function (eventArg) {
|
||||
console.log("Listener called", eventArg);
|
||||
});
|
||||
|
||||
// Register a listener
|
||||
emitter.on("messagedLogged", { id: 1, url: "http://www.example.com" });
|
||||
```
|
||||
|
||||
## Extending the `EventEmitter` class
|
||||
|
||||
- It's not best practice to call the EventEmitter class directly in `app.js`. If
|
||||
we want to use the capabilities of the class we should create our own module
|
||||
that extends `EventEmitter`, inheriting its functionality with specific
|
||||
additional features that we want to add.
|
||||
- So, refactoring the previous example:
|
||||
|
||||
```js
|
||||
// File: Logger.js
|
||||
|
||||
const EventEmitter = require("events");
|
||||
|
||||
class Logger extends EventEmitter {
|
||||
log(message) {
|
||||
console.log(message);
|
||||
this.emit("messageLogged", { id: 1, url: "http://www.example.com" });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
_The `this` in the `log` method refers to the properties and methods of
|
||||
`EventEmitter` which we have extended._
|
||||
|
||||
- We also need to refactor our listener code within `app.js` so that it calls
|
||||
the extended class rather than the `EventEmitter` class directly:
|
||||
|
||||
```js
|
||||
// File app.js
|
||||
|
||||
const Logger = require('./Logger')
|
||||
const logger = new Logger()
|
||||
|
||||
logger.on('messageLogged', function(eventArg){
|
||||
console.log('Listener called', eventArg)
|
||||
}
|
||||
|
||||
logger.log('message')
|
||||
```
|
Loading…
Add table
Reference in a new issue