Today is the 50th day of my internship in a large factory. From knowing nothing at the beginning, I can now independently take charge of the development of a certain module. I feel a lot of benefit

First, business development

1. Show/hide an element

React controls the display and hiding of elements in a variety of ways:

  • JSX embedded ternary expressions
  • JSX embedding method
  • On-line styles Set CSS properties (display, visibility, opacity)

The following is a brief summary of these writing methods

1.1. JSX embedded ternary expressions

This is often used when the presentation of an element depends on a Boolean expression

<div> <p> Paragraph 1</p> {! this.state.isButtonVisible ? <p> </p> </div>Copy the code

It’s easy to write and the code is very readable but not suitable for scenarios where the display state of the element changes frequently because it will cause the element to be re-rendered multiple times

If the element is a component, re-rendering multiple times means that component instances are constantly destroyed and recreated

1.2. JSX embedding method

When we need to render a list, we often write the list rendering part inside a method

renderList(list){ if(! this.state.isListVisible){ return null; } return ( list.map((ele, index) => ( <div key={index}>{ele.name}</div> ); ) ; }; render( const { list } = this.props; Return (< div > < / p > < p > a paragraph 1 {enclosing renderList (list)} < p > section 2 < / p > < / div >);)Copy the code

1.3. Inline Styles Set CSS properties

This is a familiar way of writing, mainly in line style to write a ternary expression is ok

< div > < p > section 1 < / p > < button style = {{display: this. State. IsButtonVisible? 'block' : 'none'}} > click on the button < / button > < p > section 2 < / p > < / div >Copy the code

There are three common ways to control element hiding:

display: none

It’s a hidden element in the true sense of the word, an element that goes right out of the flow of the document, takes no place on the page, and triggers backflow and redrawing

visibility: hidden

The element disappears visually, but still occupies its place and does not respond to user interaction to trigger a redraw

opacity: 0

The element disappears visually, but still occupies its place and responds to user interaction by triggering a redraw

(For example, binding a click event to an element will still trigger the event callback when the user clicks on the transparent area)

At the same time, the toC business needs to pay attention to security issues (to avoid situations where users manually open the developer panel and manually modify attributes, causing elements to appear).

2. Experience summary of troubleshooting problems

In front-end development, a typical link is as follows:

  • Sending network Requests
  • Receiving network Requests
  • Process the data
  • Render data

In a service development, I once encountered such a problem: after manually refreshing the page, the front-end page is not updated. In this case, you should conduct troubleshooting step by step according to the direction of the link

2.1. Send/receive network requests

This area relies on the Whistle agent

From the whistle main screen, you can see if the corresponding request has been sent and if the correct response has been received

2.2. Data processing

There may be a long way to go between the data being received and the data being passed to the corresponding component

First, if an “interceptor” is defined in the project, it is used to process (raw) raw returned data

Depending on the company/department/team, the interceptor might do the following:

Verification of retcode fields

This field is used to identify the result of the requested action: success/failure/no permission, etc

If the project is complex enough, identification fields with different names may appear for different responses, such as Retcode, code, RET, and so on

Therefore, it is important to note that the interceptor handles all cases and does the right thing

The (anti-) hump of data

  • DecamelizeKeys: Change the field name to all lowercase and separate words with underscores
  • CamelizeKeys: Remove all underscores and capitalize the first letter of the second and subsequent words

Secondly, if this link is implemented by Redux, we should also check whether the logic of data processing in Reducer is correct

When updating state, if using the destruct operator, place the updated data last:

const reducer = (state, action) => { switch(action){ case 'add': return { ... state, count: state.count + 1, }; case 'minus': return { ... state, count: state.count - 1, }; }}Copy the code

2.3 render data

If you are sure that the correct data is received, but the page is not updated, you need to check the component code according to the React rendering mechanism

For functional components, focus on the following aspects:

  • Should the component define shouldComponentUpdate
  • Whether the component is declared PureComponent
  • The life cycle

When refreshing the page manually, pay attention to whether the component’s life cycle reexecutes from constructor or only executes render. To ensure that the view is updated in a timely manner, the logic for updating data should be written into the render method. For functional components, pay attention to: Do we pass the right Dependency to useEffect? When we read external variables (such as props) in useEffect, we should put them in the second parameter (array) of useEffect to ensure that the next time the data changes, the effect will work

In addition, there are some low-level errors to check for:

  • Is there a spelling error in the field name
  • Data type error
  • Use? Whether the undefined case is handled when the

3. Other harvest/trampled pits

3.1. Inline-block sets overflow:hidden

I encountered a strange bug in the development of the dropdown box:

Only the first drop-down box is displayed normally

When the user selects from the first drop-down box and displays the second drop-down box, the position of the first drop-down box is shifted downward

It turned out that overflow: Hidden was causing the baseline alignment problem

Simple reproduction is as follows:

<style>
  .special {
    max-width: 160px;
    display: inline-block;
    overflow: hidden;
  }
  span {
    display: inline-block;
    border: 1px solid black;
  }
</style>

<div class="box">
  <span>email</span>
  <span class="special">[email protected]</span>
  <span>Change</span>
</div>
Copy the code

The renderings are as follows:Cause analysis:

First of all,, div.box and its interior form an IFC (IFC layout when block-level elements contain only inline elements)

Within IFC, elements are aligned vertically in a vertical-align manner, and the default attribute value is baseline

By default, baseline is below the lowercase letter X

The secondWhen we set Overflow: Hidden for sp.special, its baseline changes

W3C rules for this behavior are as follows:

The baseline of an ‘inline-block’ is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its ‘overflow’ property has a computed value other than ‘visible’, in which case the baseline is the bottom margin edge.

In other words, the baseline of span. Special becomes the bottom edge of its margin

Therefore, to ensure that the baseline of all elements within the IFC is consistent, other SPAN elements are moved down to their own baseline to match the baseline of SP.special

Solution: Unify the alignment of elements within an IFC box

Set vertical-align to a non-baseline value for the span element inside div.box

Also note that with display:inline-block set, the inner and outer margins also affect vertical alignment

3.2. Change the default Ant Design style

When developing with Ant Design, you may need to change the default style to suit your needs by opening the Element panel on the page via F12 and finding the className of the element you want to change (for example: Ant -input-search-button) and then write the corresponding style inside the :global() expression. Also, to avoid contaminating the global style, you need to add a className to the parent element of the target element and write the style inside the parent element

import { Input } from 'antd'; const { Search } = Input; <span className="search-box-wrapper"> <span className="search-box-wrapper">Copy the code
.search-box-wrapper{ :global(.ant-input-search-button){ height: 34px; }}Copy the code

The correct way TypeScript declares React components

When writing the React component in the. TSX file, you need to declare the props and state of the component. The class component uses interfaces to declare the types of the props and state, and uses generics to tell the component instance

import React from 'react'; interface AppProps{ style: string; } interface AppState{ name: string; } class App extends React.Component<AppProps, AppState>{ constructor(props){ super(props); this.state = { name: '', }; } render(){ return ( <div>hello,{name}</div> ); }}Copy the code

Also, initialize the necessary properties of state in constructor. If the component does not receive props, you do not need to declare the interface; just use {} instead

// No props class App extends React.Component<{}, AppState>Copy the code

Function components:

import React from 'react';

interface AppProps{
  style: string;
}

export function App(props: AppProps){
  return;
}
Copy the code

Second, interactive experience

In addition to developing the basic functionality, I also thought further about the process of user interaction

1. Provide operational feedback

On the background management page, when a user adds, edits, or deletes an item, the front-end sends a network request to the front-end user. After the front-end user receives a response from the background, it is necessary to provide feedback to the user for further operations. Common types of feedback are as follows:

  • successful
  • failure
  • Nonconformity to specification

Message is a lightweight prompt provided by Ant Design that is very simple to use and has the following benefits:

  • Use ICONS with different colors and shapes to display different types of feedback (green √ for success, red x for failure, yellow! Warning)
  • By default, it is displayed in the center at the top of the page and disappears automatically
  • Do not interrupt user operations

We can display different messages in promise.then, depending on the result of the request

AddMember = (data) => {axios.get(url, data). Then ((resp) => {message. }, (reason) => {message.error(' operation failed, please try again '); })}Copy the code

2. Display the loading state

In order to avoid too much blank space, many front-end pages use various forms to predict the loading of content, such as:

  • Skeleton screen: Shows the general structure of the page, with gray shading placeholder
  • Animation: shows a circular loading animation
  • The tooltip

The benefits of this are: In the background management system, when background data is updated, the front-end needs to send network requests. During the period from the user clicks “OK” button to send a request and the background returns a result, we can use the loading method provided by Message. Displays the information “Submit request”

After getting the requested result, manually remove it

AddMember = (data) => {const hideLoadingMessage = message.loading(' loading ', 0); axios.get(url, data) .then((resp) => { hideLoadingMessage(); }, (reason) => {hideLoadingMessage(); // Handle request failure})}Copy the code

Message. loading returns a function

callback() { if (messageInstance) { messageInstance.removeNotice(target); }}Copy the code

When we call this function in our code, it checks for the existence of the message instance we just created and destroys it if it does

Refer to the official Ant Design documentation for more usage of the Message method

3. About the drop-down menu

Dropdown is a component provided by Ant Design that can be used to hold a set of action elements. In this background management system, the Dropdown menu is used to select specific items for the user. By default, the width of the entire Dropdown component changes dynamically with the current option. In order to keep the page beautiful, you need to keep the width of the drop-down menu fixed so that when the item name is too long, it will overflow the drop-down menu

Here, we need to do something special with the corresponding SPAN tag

<span className='project-dropdown-wrapper'> < dropdown trigger={['click']}> <span> please select project </span><DownOutlined/> </a> </Dropdown> </span>Copy the code

Encapsulate in a class related styles for handling single-line text overflow (use less in the project)

Note that before you can set the width or height of a line element such as span, you must set its dispaly attribute to inline-block

.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.project-dropdown-wrapper span{
  display: inline-block;
  max-width: 160px;
  .ellipsis();
}
Copy the code

After submitting the code, my colleagues found in the review that this could be further optimized because CSS selectors are read from right to left, which means that when we use descendant selectors like.project-dropdown-wrapper span: The browser will match all the SPAN tags and then filter out the.project-Dropdown-wrapper class so it’s better to use a class selector instead of a tag selector to improve the performance of the page rendering so that we can handle the overflow style

Tooltip is a component provided by Ant Design that appears as a text prompt bubble box

It’s as simple as wrapping the target element with a Tooltip tag and setting the title attribute

<Tooltip title='thisIsTheFullNameOfMyProject'>
  <span>thisIsTheFullNameOfMyProject</span>
<Tooltip/>
Copy the code

Finally, the project name is too long & the effect picture in the drop-down box is as follows:

Write in the last

In view of the author is only a student who has not graduated, practical experience is very limited, there is wrong or bad place to write welcome everyone in the comment area criticism and correction!