Saturday, June 22, 2019

I saw Aaron Ackerman speak on hooks at the React Minneapolis Meetup on Thursday night.

Thanks to Object Partners for hosting. Before Aaron Ackerman spoke, I learned a few things in just mingling with another there. Apparently there is a smartphone app for meetup.com that allows you to search meetups by topic. He was also telling me about a server for Postgres at the Mac which kind of sounded like post-it-go in name, but likely what was meant was Postgres with Go. Material-UI is a UI framework for React as are React DnD (DnD for drag and drop) or maybe react-drag-and-drop and furthermore also thirdly react-beautiful-dnd. Aaron himself namedropped Genesis components as a forerunner to hooks, ESLint as a linter (a tool that flags errors both stylistic and much more literal errors), and Enzyme for testing React rendering while utilizing CodeSandbox (at codesandbox.io) for all of his presentation as the IDE. React version 16.8.0 and version 3 of the Create React App were the first places one could use hooks, but that said they are downwards compatible and you should be able to get them working in older stuff yet. Hooks are an opt-in and thus you may use them or not use them. The number of hooks used through a potential path through your app has to be consistent without regard to the path and you cannot nest hooks in if/then logic. As of 16.8.0 there are five built-in hooks and the whole of this talk entailed talking through them. useState was on exposition first and Aaron showed us a class component using setState and contrasted it with a functional component using useState which had half the lines of code. Both setState and useState were touched on somewhat in a training I had (I don't know React yet) as denoted here, and, as suggested here, the big difference between class and functional components in React is that the class components use the ES6 class keyword and extend Component imported from the 'react' base source while functional components are just functions. As best as I can tell both setState and useState are for altering what is in the store in the Redux shape of things. useContext is a solution to the problem of explicitly handing something down a tree of deeply nested components from top to bottom. Historically, context consumers and render props can create a pyramid of doom in these scenarios. No more! useReducer like useState takes in both state and an action and undertakes the sort of writes you might expect of reducers in the Redux pattern. The thing that is different here however is that useReducer is not putting stuff in the store. useReducer is sort of tucking stuff away in a component level store. useEffect is also Redux-flavored. This gives you a way to call out an API to get some data. It is meant for data fetching and will run when the component is mounted at the DOM. You may return a teardown function from useEffect to deal with what happens when the data actually returns. An oddity here is that useEffect runs synchronously (to avoid race conditions) so the teardown function is not a callback/promise. It made me think instead of the Dispose method on types which implement IDisposable in C# though it would tend to be used a bit differently obviously. ESLint will warn you when using the async keyword in useEffect. useRef is the last of the five. Refs are used in React to grab ahold of DOM elements and they have had a four phase history which I will detail while focusing on the bookends of history. Phase one in the early, early days was very jQueryesque. Aaron's example, as seen in the photo here, was:

import React from 'react';
import ReactDOM from 'react-dom';
 
class App extends React.Component {
   componentDidMount() {
      console.log(this.refs.container);
   }
 
   render() {
      return <div ref="container">hello</div>;
   }
}
 
let rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

 

 

Later, it was more in style to pass a function to a ref prop that runs when the component mounts. That is the second phase in our history, and the third has us using React.createRef(); At some point, we have to get into hooks and useRef correct? Yes, that is the last of the four approaches and the most modern way to go. Aaron offered up:

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
 
function TextInputWithFocusButton() {
   const inputEl = useRef(null);
   const onButtonClick = () => {
      
// 'current' points to the mounted text input element
      inputEl.current.focus();
   };
   return {
      <>
         <input ref={inputEl} type="text" />
         <button onClick={onButtonClick}>Focus the input</button>
      </>
   };
}
 
let rootElement = document.getElementById("root");
ReactDOM.render(<TextInputWithFocusButton />, rootElement);

 

 

Aaron's setState at a class component example:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
 
class Counter extends Component {
   constructor(props) {
      super(props);
      this.state = { count: 0 };
   }
   render() {
      return {
         <div
            onClick={() => {
               this.setState({ count: this.state.count + 1 });
            }}
         >
            {this.state.count}
         </div>
      };
   }
}
 
let rootElement = document.getElementById("root");
ReactDOM.render(<Counter />, rootElement);

 

 

Aaron's useState at a functional component example:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
 
let Counter = () => {
   let [count, setCount] = useState(0);
   return <div onClick={() => setCount(count + 1)}>{count}</div>
};
 
let rootElement = document.getElementById("root");
ReactDOM.render(<Counter />, rootElement);

No comments:

Post a Comment