It may be the 50 React + TypeScript specifications and experiences you need(5)

March 30, 2023 1330hotness 0likes 0comments

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
InterServer Web Hosting and VPS

Aaron

Hello, my name is Aaron and I am a freelance front-end developer

Comments