We're going to build a multi-step wizard for a jobs-to-be-done customer research questionaire from scratch.
- Installation
- What we're building
- Getting help
| /** | |
| * The Anatomy of a Remix Route | |
| */ | |
| import { parseFormBody, json, redirect } from "@remix-run/data"; | |
| import { | |
| Form, | |
| useRouteData, | |
| usePendingFormSubmit, | |
| preload, | |
| } from "@remix-run/react"; |
We're going to build a multi-step wizard for a jobs-to-be-done customer research questionaire from scratch.
| meta | ||
|---|---|---|
|
import { Link } from "react-router-dom";
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 Expo from "expo"; | |
| import { Auth } from "aws-amplify"; | |
| ... | |
| class SignInScreen extends React.Component { | |
| ... | |
| loginWithFacebook = async () => { |
| /* | |
| Open console. | |
| (Import https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.js first if you want/need number formatting) | |
| Then copy & paste this + enter, to run this. | |
| Copy console output to a NewFile.js or NewFile.jsx file. | |
| prettier --write NewFile.js | |
| */ | |
| /* eslint no-console: ["error", { allow: ["log"] }] */ | |
| /* global document, Decimal*/ | |
| (() => { |
| There is no requirement that you make a one-to-one in/out ratio. So you can emit multiple actions using flatMap if you need to: | |
| const loaded = (results) => ({type: 'RESULTS_LOADED', results}); | |
| const otherAction = (results) => ({type: 'MY_OTHER_ACTION', results}); | |
| searchEpic = (action$) => | |
| action$ | |
| .ofType('SEARCH') | |
| .mergeMap( | |
| Observable |
| import { join } from 'path' | |
| import { readdir, stat } from 'fs-promise' | |
| async function rreaddir (dir, allFiles = []) { | |
| const files = (await readdir(dir)).map(f => join(dir, f)) | |
| allFiles.push(...files) | |
| await Promise.all(files.map(async f => ( | |
| (await stat(f)).isDirectory() && rreaddir(f, allFiles) | |
| ))) | |
| return allFiles |
A complete list of RxJS 5 operators with easy to understand explanations and runnable examples.
| import React, {DeviceEventEmitter} from 'react-native'; | |
| import {Observable} from 'rx-lite' | |
| /** | |
| * Creates an Observable to listen to any event of DeviceEventEmitter | |
| * @param type {string} Event type | |
| */ | |
| export default createObservableFromDeviceEventEmitter$ = type => { | |
| let subscription; | |
| return Observable.fromEventPattern( |
| var ProjectForm = React.createClass({ | |
| getInitialState: function() { | |
| return { headerText: 'nothing' } | |
| }, | |
| handleToggleChange: function(value) { | |
| this.setState({ headerText: value.toUpperCase() }) | |
| }, | |
| render: function() { | |
| return ( | |
| <form> |