react#unstable_useTransition JavaScript Examples
The following examples show how to use
react#unstable_useTransition.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: EditButton.client.js From Lambda with MIT License | 6 votes |
export default function EditButton({noteId, children}) {
const [, setLocation] = useLocation();
const [startTransition, isPending] = unstable_useTransition();
const isDraft = noteId == null;
return (
<button
className={[
'edit-button',
isDraft ? 'edit-button--solid' : 'edit-button--outline',
].join(' ')}
disabled={isPending}
onClick={() => {
startTransition(() => {
setLocation((loc) => ({
selectedId: noteId,
isEditing: true,
searchText: loc.searchText,
}));
});
}}
role="menuitem"
>
{children}
</button>
);
}
Example #2
Source File: SearchField.client.js From Lambda with MIT License | 6 votes |
export default function SearchField() {
const [text, setText] = useState('');
const [startSearching, isSearching] = unstable_useTransition(false);
const [, setLocation] = useLocation();
return (
<form className="search" role="search" onSubmit={(e) => e.preventDefault()}>
<label className="offscreen" htmlFor="sidebar-search-input">
Search for a note by title
</label>
<input
id="sidebar-search-input"
placeholder="Search"
value={text}
onChange={(e) => {
const newText = e.target.value;
setText(newText);
startSearching(() => {
setLocation((loc) => ({
...loc,
searchText: newText,
}));
});
}}
/>
<Spinner active={isSearching} />
</form>
);
}
Example #3
Source File: SidebarNote.client.js From Lambda with MIT License | 5 votes |
export default function SidebarNote({id, title, children, expandedChildren}) {
const [location, setLocation] = useLocation();
const [startTransition, isPending] = unstable_useTransition();
const [isExpanded, setIsExpanded] = useState(false);
const isActive = id === location.selectedId;
// Animate after title is edited.
const itemRef = useRef(null);
const prevTitleRef = useRef(title);
useEffect(() => {
if (title !== prevTitleRef.current) {
prevTitleRef.current = title;
itemRef.current.classList.add('flash');
}
}, [title]);
return (
<div
ref={itemRef}
onAnimationEnd={() => {
itemRef.current.classList.remove('flash');
}}
className={[
'sidebar-note-list-item',
isExpanded ? 'note-expanded' : '',
].join(' ')}
>
{children}
<button
className="sidebar-note-open"
style={{
backgroundColor: isPending
? 'var(--gray-80)'
: isActive
? 'var(--tertiary-blue)'
: '',
border: isActive
? '1px solid var(--primary-border)'
: '1px solid transparent',
}}
onClick={() => {
startTransition(() => {
setLocation((loc) => ({
selectedId: id,
isEditing: false,
searchText: loc.searchText,
}));
});
}}
>
Open note for preview
</button>
<button
className="sidebar-note-toggle-expand"
onClick={(e) => {
e.stopPropagation();
setIsExpanded(!isExpanded);
}}
>
{isExpanded ? (
<img
src="chevron-down.svg"
width="10px"
height="10px"
alt="Collapse"
/>
) : (
<img src="chevron-up.svg" width="10px" height="10px" alt="Expand" />
)}
</button>
{isExpanded && expandedChildren}
</div>
);
}
Example #4
Source File: NoteEditor.client.js From Lambda with MIT License | 4 votes |
export default function NoteEditor({noteId, initialTitle, initialBody}) {
const refresh = useRefresh();
const [title, setTitle] = useState(initialTitle);
const [body, setBody] = useState(initialBody);
const [location, setLocation] = useLocation();
const [startNavigating, isNavigating] = unstable_useTransition();
const [isSaving, saveNote] = useMutation({
endpoint: noteId !== null ? `/notes/${noteId}` : `/notes`,
method: noteId !== null ? 'PUT' : 'POST',
});
const [isDeleting, deleteNote] = useMutation({
endpoint: `/notes/${noteId}`,
method: 'DELETE',
});
async function handleSave() {
const payload = {title, body};
const requestedLocation = {
selectedId: noteId,
isEditing: false,
searchText: location.searchText,
};
const response = await saveNote(payload, requestedLocation);
navigate(response);
}
async function handleDelete() {
const payload = {};
const requestedLocation = {
selectedId: null,
isEditing: false,
searchText: location.searchText,
};
const response = await deleteNote(payload, requestedLocation);
navigate(response);
}
function navigate(response) {
const cacheKey = response.headers.get('X-Location');
const nextLocation = JSON.parse(cacheKey);
const seededResponse = createFromReadableStream(response.body);
startNavigating(() => {
refresh(cacheKey, seededResponse);
setLocation(nextLocation);
});
}
const isDraft = noteId === null;
return (
<div className="note-editor">
<form
className="note-editor-form"
autoComplete="off"
onSubmit={(e) => e.preventDefault()}
>
<label className="offscreen" htmlFor="note-title-input">
Enter a title for your note
</label>
<input
id="note-title-input"
type="text"
value={title}
onChange={(e) => {
setTitle(e.target.value);
}}
/>
<label className="offscreen" htmlFor="note-body-input">
Enter the body for your note
</label>
<textarea
id="note-body-input"
value={body}
onChange={(e) => {
setBody(e.target.value);
}}
/>
</form>
<div className="note-editor-preview">
<div className="note-editor-menu" role="menubar">
<button
className="note-editor-done"
disabled={isSaving || isNavigating}
onClick={() => handleSave()}
role="menuitem"
>
<img
src="checkmark.svg"
width="14px"
height="10px"
alt=""
role="presentation"
/>
Done
</button>
{!isDraft && (
<button
className="note-editor-delete"
disabled={isDeleting || isNavigating}
onClick={() => handleDelete()}
role="menuitem"
>
<img
src="cross.svg"
width="10px"
height="10px"
alt=""
role="presentation"
/>
Delete
</button>
)}
</div>
<div className="label label--preview" role="status">
Preview
</div>
<h1 className="note-title">{title}</h1>
<NotePreview title={title} body={body} />
</div>
</div>
);
}