41. If you need to optimize react performance (generally not needed)
- if both state and props of a component are simple types, you can inherit PureComponent instead of Component
import { Component, PureComponent } from 'react';
// bad
class Message extends Component {
render() {
return <span>{this.state.message}</span>;
}
}
// good
class Message extends PureComponent {
render() {
return <span>{this.state.message}</span>;
}
}
- override the shouldComponentUpdate method to determine whether re-rendering is needed in shouldComponentUpdate based on whether the state,props has changed. If the component inherits PureComponent, there is no need to override the shouldComponentUpdate method
import { isReactPropsEqual, isReactStateEqual } from '@fe/common/lib/equal';
shouldComponentUpdate(nextProps:IProps, nextState:IState) {
if (isReactStateEqual(nextState,this.state) && isReactPropsEqual(nextProps,this.props)) {
return false;
}
return true;
}
42. Event event object type
many friends have used ts for a long time, but they don't know the common Event event object types:
ClipboardEvent Clipboard event object
DragEvent drag event object
ChangeEvent Change event object
KeyboardEvent keyboard event object
MouseEvent mouse event object
TouchEvent Touch event object
WheelEvent wheel event object
AnimationEvent animated event object
TransitionEvent transition event object
import { MouseEvent } from 'react';
interface IProps {
onClick(event: MouseEvent<HTMLDivElement>): void;
}
43. Replace state status with private attributes
for some status attributes that do not need to control ui, we can bind them directly to this, that is, private attributes. There is no need to apply them to this.state, otherwise the rendering mechanism will be triggered and performance will be wasted. For example, when we request paging data, we will have a variable.
// bad
state: IState = {
pageNo:1,
pageSize:10
};
// good
queryParams:Record<string,any> = {
pageNo:1,
pageSize:10
}
44. Thinking about fine-grained code
summarize four sentences. When we write components or functions, we extract tool functions from business logic, form checksum from business, event functions from business, ajax from business. For example, some pages are redirected through location.href, and some of our business logic is put into didmountMount, but if you change the requirements later, you may have to use react-router to jump, and there may be a lot of logic to change, so if the function is extracted, the code will be changed less when the requirement is updated.
If you are not sure how to divide the fine granularity of a function, I have a suggestion. If you have used the code more than twice, if you want to extract the component or function, you can not use
if you use it twice.
45. There are too many judgments such as if else, which is difficult to maintain in the later stage.
personally, I think if else nesting doesn't look too bad, but the sad thing is that after a long iteration of the project, I forget to write this code, and there are many types or are not sure what type, and whether it will be added later, it is very complicated to change, and it is easy to step on the hole and carry the pot. To replace if nesting with configuration is probably to pull out a config.ts and put some configurations in it.
For example, in your business code, the code will execute different logic based on different url parameters.
/info?type=wechat&uid=123456&
const qsObj = qs(window.location.url)
const urlType = qsObj.type
// bad
if (urlType === 'wechat') {
doSomeThing()
} else if () {
doSomeThing()
} else if () {
doSomeThing()
} else if () {
doSomeThing()
}
// good
config.t
const urlTypeConfig: Record<string, typeItem> = {
'wechat': { // The key is the corresponding type
name: 'wechat',
show: ['header', 'footer', 'wechat'] // Show what, possibly asynchronous
pession: ['admin'], // What is the permission? It may be asynchronous
},
'zhifubao': { // The key is the corresponding type
name: 'zhifubao',
show: ['header', 'footer', 'zhifubao'] // Show what, possibly asynchronous
pession: ['admin'], // What is the permission? It may be asynchronous
},
}
// Business logic
const qsObj = qs(window.location.url)
const urlType = qsObj.type
Object.keys(urlTypeConfig).forEach(item => {
if(urlType === item.type) {
doSomeThing(item.show)
}
})
46. Don't use renderXXX, use functional components
found that some members of the team split some elements into the function in order to reduce the amount of code in the render function.
// bad
renderHeader = () => {
return (<div />)
}
renderBody = () => {
return (<div />)
}
renderFooter = () => {
return (<div />)
}
render(){
return(
<div>
renderHeader()
renderBody()
renderFooter()
</div>
)
}
A better way is to use functional components instead of writing methods in the current component
// good
function RenderHeader(props) = {
return (<div />)
}
function RenderBody(props) = {
return (<div />)
}
function RenderFooter(props) = {
return (<div />)
}
class Component extends React.Component<iProps, iState>{
render () {
return(
<div>
<RenderHeader />
<RenderBody />
<RenderFooter />
</div>
)
}
}
47. A tag security issues
Security issues during opening a new window using the a tag. Window.opener can be used to control the original page in the new page. If the old and new pages are in the same domain, you can manipulate the original page at will in the new page. If the domain is different, the location object of the original page can still be accessed through window.opener.location in the new page
add the rel= "noopener" attribute to the a tag with target= "_ blank". If you open the page using window.open, leave the opener object empty.
var newWindow = window.open();
newWindow.opener = null;
48. Void 0 replaces undefined
clearSessioin = () => {
req.session.userName = undefined;
req.session.userName = void 0
}
49. Do not operate cookie at the front end
when doing some front-end authentication, the backend should enable domain,secure,httponly strict mode, prohibit the frontend from operating cookie, and prevent csrf attacks.
50. Code Review plug-in
We can use the build tool to inherit husky eslint tslint lint-stage prettier to standardize the code.
- eslint-config-prettier
- eslint-plugin-prettier
- eslint-plugin-react
- tslint-react
- tslint-plugin-prettier
- tslint-config-prettier
- team development workflow