How to go back to home in React
Issue #665
Usually in header we have logo that takes user back to the home page
1 | // index.js |
1 | // Header.js |
Issue #665
Usually in header we have logo that takes user back to the home page
1 | // index.js |
1 | // Header.js |
Issue #664
Use moment-timezone https://momentjs.com/timezone/docs/
1 | npm install moment-timezone |
Need to import from moment-timezone
, not moment
1 | import moment from 'moment-timezone' |
Issue #663
1 | /** @jsx jsx */ |
Updated at 2020-06-17 05:38:30
Issue #662
Use spread operator
1 | import React, { Component, useState, useEffect } from 'react'; |
Updated at 2020-06-12 21:23:42
Issue #661
Use Bulma css
1 | <input |
Updated at 2020-06-16 07:30:52
Issue #661
Use Bulma css
1 | <input |
Issue #660
Apply tintColor
does not seem to have effect.
1 | datePicker.setValue(UIColor.label, forKeyPath: "textColor") |
Updated at 2020-06-10 19:15:21
Issue #659
Use useLocation
https://reacttraining.com/react-router/web/guides/scroll-restoration
1 | import React, { useEffect } from 'react'; |
Updated at 2020-06-04 05:58:47
Issue #658
Declare routes, use exact
to match exact path as finding route is from top to bottom. For dynamic route, I find that we need to use render and pass the props manually.
Declare Router
as the rooter with Header, Content and Footer. Inside Content there is the Switch
, so header and footer stay the same across pages
1 | import { |
To trigger route request, use useHistory
hook. Note that we need to declare variable, and not use useHistory().push
directly
1 | import { useHistory } from 'react-router-dom' |
To get parameters, use match
1 | export default function BookDetail(props) { |
Updated at 2020-06-03 05:07:00
Issue #657
Add library folder src/library
1 | src |
Declare package.json in library
folder
1 | { |
Declare library as dependency in root package.json
1 | "dependencies": { |
Now import like normal, for example in src/screens/Home/index.js
1 | import res from 'library/res' |
Issue #656
Lately I’ve been challenging myself to declare switch statement in SwiftUI, or in a more generalized way, execute any anonymous function that can return a View
Note that this approach does not work yet, as TupeView
should support variadic number of contents, and also T.RawValue needs to conform to Equatable in order to check the cases.
Also in Switch statement, Content can’t be inferred
1 | struct Case<T: RawRepresentable, Content: View>: View { |
Another solution is to use a MakeView
view, this is more generic as it can execute any functions
1 | enum Animal: String { |
Updated at 2020-05-22 20:42:14
Issue #655
Declare state
and setState
1 | export default function Showcase(props) { |
Issue #654
Use shelljs
to execute shell commands, and fs
to read and write. In public/index.html
specify some placeholder and we will replace those in our script
1 | const fs = require('fs'); |
Issue #654
A good landing page is one of the most crucial part of a successful launch. Recently I started creating landing pages for my apps, I was lazy that I ended creating a white label React app as a landing template and then write a script to build multiple similar pages.
Here are a few examples, at first the pages share same look and feel, but we can add more configuration parameters later on. The cool thing with this approach is fixing bugs and adding features become easier, as they will all be deployed with the generator script.
Here are how it looks in my apps PastePal and PushHero, look at how the footer parts are so consistent.
The first version that I built is with pure html and javascript. It has a lot of boilerplate and I need to deal with Webpack eventually to obfuscate my code.
1 | const cards = Array.from(apps).map((app) => { |
Since they are in pure html and javascript, everyone can just open browser and view source code, which is not ideal, so I need to fiddle with Webpack and other uglify and minimize tools to obfuscate the code, like How to use webpack to bundle html css js
1 | npm init |
And with external css sheets, finding and renaming class list names take some time.
I use create-react-app to generate my React app as it sets up JSX, Babel, Webpack, hot reloading and development server for me.
I like js, css and html be part of the same component file, so I prefer inline css. I tried styled-components before but then I found emotion to be much easier to use and close to css. I also don’t like declaring unnecessary local variables style in styled-components.
Here is a good comparison between the 2 styled-components-vs-emotion
1 | // styled-components |
1 | // emotion |
I detail here How to use emotion for inline css in React
Emotion has core and styled styles. I usually use the css
inline syntax, so I can just install the core
1 | npm i @emotion/core |
Note that we have to declare jsx directive at the top of every file.
1 | // this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement |
One cool thing with inline css is they are just javascript code so it’s pretty easy to apply logic code, like in How to conditionally apply css in emotion js
1 | const shadowCss = feature.shadow ? css` |
When a component gets too big, I extract it to small components, in the end I have a bunch of them
1 | import Footer from './components/Footer' |
and I stack them vertically, using flexbox and css grid
I used flexbox mostly at first, but then I gradually convert some of them to css grid when I see fit. To stack vertically with flexbox, I use flex-direction
1 | display: flex; |
where as in css grid items are stacked vertically by default, if we want multiple columns, specify grid-template-columns
1 | display: grid; |
I use flex-wrap: wrap
in some places to wrap content, but in some places I see specifying media query and changing columns in css grid is more easier and predictable
1 | display: grid; |
Google Lighthouse is the most popular tool to audit website for performance and SEO. I use it to reduce image size, add correct html attributes and make it more SEO friendly.
I have my list of apps in 1 javascript file, called factory.js
, for example here with PastePal
1 | const factory = [ |
In my package.json
for my landing page, I declare a property called currentApp
. This is to specify which app I’m currently work on. Later in the generator script, we can just update this for every app that we build.
1 | { |
Here is how to read that value from my landing app
1 | import factory from './apps/factory' |
One thing with create-react-app is that built assets are relative to the root, not your index.html
npm run build creates a build directory with a production build of your app. Set up your favorite HTTP server so that a visitor to your site is served index.html, and requests to static paths like /static/js/main.
.js are served with the contents of the /static/js/main. .js file. For more information see the production build section.
If you are not using the HTML5 pushState history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your package.json:
1 | "homepage": ".", |
This will make sure that all the asset paths are relative to index.html. You will then be able to move your app from http://mywebsite.com to http://mywebsite.com/relativepath or even http://mywebsite.com/relative/path without having to rebuild it.
I make another nodejs project called generator
, it will use my landing project as template, changes a few parameters and build each app defined in factory.js
.
My factory use export default
syntax, so I need to use Babel in my node app to import that, see How to use babel 7 in node project
1 | npm init generator |
1 | { |
I use sync
methods of fs
to not have to deal with asynchrony.
1 | const pkPath = `/Users/khoa/projects/anding/package.json` |
I use shelljs
to execute shell commands, and fs
to read and write. In public/index.html
specify some placeholder and we will replace those in our script.
In landing app, the public/index.html
acts as the shell when building the app, so I have a few placeholder called CONSTANTS
, these will be replaced at generation time in my node app.
1 | const fs = require('fs'); |
Updated at 2020-05-14 04:25:39
Issue #653
Use https://github.com/biati-digital/glightbox
Configure css. Specify class='glightbox
for html elements
1 | <link rel="stylesheet" href="css/blueimp-gallery.min.css" /> |
Install package
1 | npm install glightbox |
1 | const lbElements = features.map((feature) => { |
Issue #652
Use https://github.com/michalsnik/aos
Add link to head
1 | <head> |
Jus before closing body tag
1 | <script src="https://unpkg.com/aos@next/dist/aos.js"></script> |
Specify data-aos
1 | <div data-aos="fade-up"> |
Issue #651
Use shelljs
1 | npm install shelljs |
1 | const shell = require('shelljs') |
The -a option is an improved recursive option, that preserve all file attributes, and also preserve symlinks.
The . at end of the source path is a specific cp syntax that allow to copy all files and folders, included hidden ones.
Updated at 2020-05-07 04:10:05
Issue #650
Install
1 | npm install @babel/core |
Configure .babelrc
1 | { |
In package.json
, transpile using npx babel
then node dist/index.js
1 | "start": "cp ../landing/src/apps/factory.js copied/factory.js && npx babel index.js --out-file dist/index.js && npx babel copied/factory.js --out-file dist/factory.js && node dist/index.js" |
Issue #649
Check flag then define css
1 | const Picture = (feature) => { |
Issue #648
In a similar fashion to plain old javascript, note that href
needs to have valid hash tag, like #features
1 | <a |
Updated at 2020-05-06 08:36:21
Issue #647
emotion
can be used in framework agnostic or with React. To use with React, follow https://emotion.sh/docs/introduction#react
1 | npm i @emotion/core |
Note that you must have /** @jsx jsx */
at the top of the file, and the unused jsx
in import is a directive for JSX to work properly
1 | // this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement |
Issue #646
Pass DispatchQueue
and call queue.sync
to sync all async works before asserting
Use DispatchQueueType
and in mock, call the work immediately
1 | import Foundation |
Issue #645
1 | npm init |
1 | module.exports = { |
To invoke webpack, run below. Your output is dist/index.js
1 | npx webpack |
1 | npm install babel-minify-webpack-plugin --save-dev |
1 | npm install html-webpack-plugin --save-dev |
1 | const MinifyPlugin = require('babel-minify-webpack-plugin'); |
TBD
Copy files from dist
to public folder so we can use
1 | npm install copyfiles -g |
Then in package.json
1 | "scripts": { |
Then run npm run copy
Updated at 2020-04-28 13:18:40
Issue #644
1 | import XCTest |
Updated at 2020-04-28 09:23:59
Issue #643
Use material icons
1 | <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
1 | div#filter-container { |
1 | filters.forEach((filter) => { |
Updated at 2020-04-27 22:03:13
Issue #642
Specify container with flex-wrap
and justify-content
, and item with float: left
1 | div.cards { |
Issue #641
Create a new page
1 | hexo new page mydemo |
Remove index.md
and create index.html
, you can reference external css and js in this index.html
. Hexo has hexo new page mydemo --slug
but it does not support page hierarchy
Specify no layout so it is independent page.
1 | --- |
Issue #640
1 | async function useCache( |
1 | useCache( |
Issue #639
Never use String(format: "%.2f %%", 1.2
because each region can have different separator and placement of percent sign.
Use NumberFormatter
instead
1 | let formatter = NumberFormatter() |
1 | formatter.locale = Locale(identifier: "en_US") |
Note that the space created by NumberFormatter
is a non breakable space \u{00a0}
, which can be created by Alt Space
. This non breakable space is useful in UILabel
when you want the whole word to stick together
Issue #638
Use commandDefinitions
in XCSourceEditorExtension
.
1 | import Foundation |
There is a weird crash that we can’t seem to declare functions or use commandDefinitions
, the workaround is to declare in plist