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!