Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
React Conf 2018 -- new functional component APIs https://reactjs.org/docs/hooks-intro.html
// Basic example of useState.
import React, { useState } from 'react';
export default function Greeting(props) {
const [name, setName] = useState('Mary');
function handleNameChange(e) {
setName(e.target.value);
}
return (
<section>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
</section>
);
}
// Example using multiple hooks in the same component.
import React, { useState } from 'react';
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
</section>
);
}
// There's also a useContext for consuming context in functional componenets.
import React, { useState, useContext } from 'react';
import { ThemeContext, LocaleContext } from './context';
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section className={themee}>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
<Row label="Language">
{locale}
</Row>
</section>
);
}
// For component lifecycles/side effects, there's useEffect.
// This example sets the browser tab title.
import React, { useState, useContext, useEffect } from 'react';
import { ThemeContext, LocaleContext } from './context';
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
useEffect(() => {
document.title = name + ' ' + surname;
});
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section className={theme}>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
<Row label="Language">
{locale}
</Row>
</section>
);
}
// You can have multiple effects.
import React, { useState, useContext, useEffect } from 'react';
import { ThemeContext, LocaleContext } from './context';
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
useEffect(() => {
document.title = name + ' ' + surname;
});
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
// Can return a function to "clean up" the effect on unmount.
return () => {
window.removeEventListener('resize', handleResize);
}
});
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section className={theme}>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
<Row label="Language">
{locale}
</Row>
<Row label="Width">
{width}
</Row>
</section>
);
}
// You can extract effects into separate functions (which can be
// shared across files, from npm packages, etc)
import React, { useState, useContext, useEffect } from 'react';
import { ThemeContext, LocaleContext } from './context';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
// Can return a function to "clean up" the effect on unmount.
return () => {
window.removeEventListener('resize', handleResize);
}
});
return width;
}
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
const width = useWindowWidth();
useEffect(() => {
document.title = name + ' ' + surname;
});
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section className={theme}>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
<Row label="Language">
{locale}
</Row>
<Row labele="Width">
{width}
</Row>
</section>
);
}
// Extracted effect functions can also take arguments
import React, { useState, useContext, useEffect } from 'react';
import { ThemeContext, LocaleContext } from './context';
function useDocumentTitle(title) {
useEffect(() => {
document.title = title;
});
}
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
// Can return a function to "clean up" the effect on unmount.
return () => {
window.removeEventListener('resize', handleResize);
}
});
return width;
}
export default function Greeting(props) {
const [name, setName] = useState('Mary');
const [surname, setSurname] = useState('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
const width = useWindowWidth();
// Extracted effects can accept arguments as well.
useDocumentTitle(name + ' ' + surname);
function handleNameChange(e) {
setName(e.target.value);
}
function handleSurnameChange(e) {
setSurname(e.target.value);
}
return (
<section className={theme}>
<Row label="Name">
<input
value={name}
onChange={handleNameChange}
/>
</Row>
<Row label="Surname">
<input
value={surname}
onChange={handleSurnameChange}
/>
</Row>
<Row label="Language">
{locale}
</Row>
<Row labele="Width">
{width}
</Row>
</section>
);
}
// Here's an example of extracting out a generic hook to handle
// the input state/change handlers in the form
import React, { useState, useContext, useEffect } from 'react';
import { ThemeContext, LocaleContext } from './context';
function useDocumentTitle(title) {
useEffect(() => {
document.title = title;
});
}
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
// Can return a function to "clean up" the effect on unmount.
return () => {
window.removeEventListener('resize', handleResize);
}
});
return width;
}
function useFormInput(initialValue) {
const [value, setValue] = useState(initialValue);
function handleChange(e) {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
};
}
export default function Greeting(props) {
const name = useFormInput('Mary');
const surname = useFormInput('Poppins');
const theme = useContext(ThemeContext);
const locale = useContext(LocaleContext);
const width = useWindowWidth();
// Extracted effects can accept arguments as well.
useDocumentTitle(name + ' ' + surname);
return (
<section className={theme}>
<Row label="Name">
<input {...name} />
</Row>
<Row label="Surname">
<input {...surname} />
</Row>
<Row label="Language">
{locale}
</Row>
<Row labele="Width">
{width}
</Row>
</section>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.