Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
ryanflorence / farty fart
Created November 24, 2020 05:31
Created from Remix Form!
fart fart fart
meta
title
Mutations with Actions and Form | Remix

import { Link } from "react-router-dom";

Mutations with Actions and <Form>

Data mutations in Remix are built on top of two fundamental web APIs: `` and HTTP. We then use progressive enhancement to enable optimistic UI, loading indicators, and validation feedback--but the programming model is still built on HTML forms.

import type { Action, Loader } from "@remix-run/loader";
import { json, parseFormBody, redirect } from "@remix-run/loader";
import { readTodos, createTodo, deleteTodo } from "../data/todo";
let action: Action = async ({ request, context: { session } }) => {
let [method, body] = await methodOverride(request);
await new Promise((res) => setTimeout(res, 1000));
switch (method) {
case "post": {
let [_, error] = await createTodo(body!.name);
///////////////////////////////////////////////////////////
// loader
const { db } = require("../server/firebase");
module.exports = () => {
return db.doc("some/path").get().data();
};
///////////////////////////////////////////////////////////
// Non-remix hook for docs, takes initial data for immediate
// rendering
{
"workbench.tree.indent": 22,
"workbench.colorCustomizations": {
"statusBar.background": "#eee",
"statusBar.noFolderBackground": "#222225",
"statusBar.debuggingBackground": "#511f1f"
},
"editor.tabSize": 2,
"editor.fontFamily": "Source Code Pro",
"window.zoomLevel": 1,
import React from "react";
import { Meta, Scripts, Styles, Routes } from "@remix-run/react";
import { useLocation } from "react-router-dom";
let noScriptPaths = new Set(["/", "/buy", "/logout", "/features", "/privacy"]);
export default function App() {
let location = useLocation()
let includeScripts = !noScriptPaths.has(location.pathname);
let { lang }= useLocalization()
import React from "react";
import { Meta, Scripts, Styles, Routes } from "@remix-run/react";
import { useLocation } from "react-router-dom";
let noScriptPaths = new Set(["/", "/buy", "/logout", "/features", "/privacy"]);
export default function App() {
let location = useLocation()
let includeScripts = !noScriptPaths.has(location.pathname);
// put markdown files in articles/*.md
// run `node build.mjs`
// upload to a host
import path from "path";
import { promises as fs } from "fs";
import shell from "shelljs";
import cheerio from "cheerio";
import remark from "remark";
import html from "remark-html";
import report from "vfile-reporter";
function CopyButton({ value }) {
let [copied, setCopied] = React.useState();
let hydrated = usePageIsHydrated();
React.useEffect(() => {
let id = setTimeout(() => setCopied(false), 2000);
return () => clearTimeout(id);
}, [copied]);
return (
<button
// don't clutter up lines with function blocks
let obj = items.reduce((memo, item) => {
memo[item.id] = item.name;
return memo;
});
// just use the comma operator for super clean code!
let obj = items.reduce((memo, item) => (memo[item.id] = item.name, memo));
// lol