Tips
GitbookKb2021-03-03
📑 前端 Node-sass 无法下载问题
Q
: node-sass issue:
$ yarn add node-sass --unsafe-perm
$ npm install node-sass --unsafe-perm
Q
: master branch and ‘origin/master’ have diverged, how to ‘undiverge’ branches’?
$ git pull --rebase origin master
也可以通过配置 yarn 国内镜像来解决:
- NPM
$ npm config set registry http://registry.npm.taobao.org
$ npm config set sass-binary-site http://npm.taobao.org/mirrors/node-sass
- YARN
$ yarn config set registry http://registry.npm.taobao.org
$ yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass
- 全局:
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
📑 用 strftime 配置 log:
console.log(
strftime("%H:%M:%S") +
" | " +
req.method +
" -> " +
req.baseUrl +
" -> " +
JSON.stringify(req.query)
);
You don’t need the body-parser
middleware, you need the raw
req stream.
gateway
server 只是代理,不做处理,所有不需要body-parser
.
📑 express, router
var router = express.Router([options]);
options -> strict: 启用严格路由。 默认情况下禁用,“/foo”和“/foo/”由路由器处理相同。
📑 dotenv, localenv
- 优先~/.bash_profile 中的 export
- .env 有效
require('dotenv').config();
process.env...
- .env.local
require('localenv').config();
process.env...
- ‘.env’ should be committed
- A way to override variables in ‘.env’ by ‘.env.local’ (which shouldn’t be committed)
.env files should be checked into source control (with the exclusion of .env*.local).
📑 component types
- State-full or class-based components
- State-less or function-based components
- Presentational (or high-order) components
- Container components
📑 Data-Down, Actions-Up
Best Practices List
- When using ReduxJS, split your Reducer code into smaller methods to avoid huge JSON within your Reducer.
- Consider using TypeScript in your apps if you do not do it already.
- Use the create-react-app generator to bootstrap your ReactJS app.
- Keep your code DRY. Don’t Repeat Yourself, but keep in mind code duplicate is NOT always a bad thing.
- Avoid having large classes, methods or components, including Reducers.
- Use more robust managers to manage application state, such as Redux.
- Use event synchronizer, such as Redux-Thunk, for interactions with your back end API.
- Avoid passing too many attributes or arguments. Limit yourself to five props that you pass into your component.
- Use ReactJS defaultProps and ReactJS propTypes.
- Use linter, break up lines that are too long.
- Keep your own jslint configuration file.
- Always use a dependency manager with a lock file, such as NPM or yarn.
- Test your commonly accessed code, code that is complex and prone to bugs.
- Write more tests that give more test coverage for your code with a little effort and test code to ensure its proper functioning.
- Every time you find a bug, make sure you write a test first.
- Use function-based components by starting to use React Hooks, a new ReactJS way to create state-full components.
- Use ES6 de-structuring for your props.
- Use conditional rendering.
- User
map()
to collect and render collections of components. - Use partial components, such as
<>
…</>
- Name your event handlers with handle prefixes, such as
handleClick()
orhandleUpdate()
. - Use
onChange
to control your inputs, such asonChange={this.handleInputChange()}
. - Use JEST to test your ReactJS code.
📑 Server-side import
Tried but not work. node-pre-gyt dependency @babel
version 6.26.3
which not supported by babel-register
.
Except import
, es6 other features like destruct
, arrow function
all work.
📑 How to access DOM?
// or a ref setter function
const ref = React.createRef();
// render
<Button ref={ref} />;
// usage
const element = ref.current;
class AccordionWrapper extends Component {
state = { title: "" };
ref = React.createRef();
handleTitle = (title) => {
this.setState({ title });
};
render() {
return (
<Accordion title={this.state.title} isOpen>
<Amendments ref={this.ref} handleTitle={this.handleTitle} />
</Accordion>
);
}
}
🪕HOC
const withHideLoading = (BaseComponent) =>
(props) => (
{props.loading &&
<BaseComponent />}
)
const ButtonWithLoading =
withHideLoading(<SubmitButton
label="Submit"
/>)
<ButtonWithLoading loading={true} />
const withDisabledState = withState("disabled", "setDisabled", false);
const withDisabledOnSubmit = withHandlers({
onSubmit: ({ setDisabled }) => () => setDisabled(true),
});
const SubmitButton = ({ label, onSubmit, disabled }) => (
<input type="submit" disabled={disabled} value={label} onClick={onSubmit} />
);
const ButtonWithDisable = compose(
withDisabledState,
withDisabledOnSubmit
)(<SubmitButton label="submit" />);
class HorizontalSplit extends React.Component {
shouldComponentUpdate() {
return false;
}
render() {
<FlexContainer>
<div>{this.props.leftSide}</div>
<div>{this.props.rightSide}</div>
</FlexContainer>;
}
}
return React.Children.only(this.props.children);
React.Children.only(
React.cloneElement(this.props.children, { editor: this.editor })
);
🪕 Hooks
Refs
provide a way to accessDOM nodes
orReact elements
created in the render method.- Instead of exposing
open()
andclose()
methods on aDialog
component, pass anisOpen
prop to it. useCallback(fn, deps)
is equivalent touseMemo(() => fn, deps)
.- the function passed to
useMemo
runs duringrendering
. Don’t do anything there that you wouldn’t normally do whilerendering
. For example side effects belong inuseEffect
, notuseMemo
. - everytime
state
changes, function will re-exectue, so useuseMemo
,useCallback
to preventstate
changes. - useEffect(func, [denpendencies])
(if dependencies=obj{}, using
useMemo
to cache )
Array.from( new Set(repeated_array) )
[ ...new Set(repeated_array) ]
📑 useRef
useRef
will give you the same ref object on every render.-
useRef
not render when change, completely separate to component function.- access dom
- persist values across renders without causing re-rendering.
- forwardRef