More sophisticated business code - start cooking
1. Background & Demand Analysis
1.1 Background
One day, I was held in the background with a good management system implemented by a single person and said that the need to achieve better than a framework.
Address: pig4cloud
1.2 Demand Analysis
Requirements: Implementing Tag tag in browser in management system
Analysis:
- Switching Tag does not actively update the page (emphasis)
- Switch off Tag in the activity to the latter
- If you close Tag for the last one, switch to the previous one
2. Implementation logic
Technology stack: react + react-router + react-redux + react-saga
Focus: Component updates, page unchanged
2.1 Memory Logic
Idea: But divided into active memory and open memory, two memory colleagues update, switch Tag to fetch data from an open array, use the data, and initiate requests without data.
- Tag array clicked on the tagList sidebar
- Tag of active Tag activity state
The operation is also in Reduce, which facilitates the internal and external interaction of subsequent Tag s.
/*. Directory: / src/store/index.js */ const appReducer ={ tabListStatus: (state = { tabList: [], activeTab: null }, action) => { switch (action.type) { case 'tabListChange': // case 'tabListAdd': // case 'tabListRemove': // case 'tabListClear': // default: return state } }, // ... }
All memory initial states are operated in App. JS - > component DidUpdate lifecycle memory
/* Directory: / src/App.js */ componentDidUpdate(prevProps, prevState) { if (this.props.tabListStatus !== prevProps.tabListStatus) { const { tabList, activeTab } = this.props.tabListStatus sessionStorage.setItem('tabList', JSON.stringify(tabList)) sessionStorage.setItem('activeTab', JSON.stringify(activeTab)) this.setState({ tabList, activeTab: activeTab !== null ? activeTab.key : '/' }) } }
2.2 External Interaction Logic
- Side Bar Logic, Added
- Click Logic to Switch Tag
- Close Tag
class App extends Component { // Click on the sidebar handleOnMenuItem = param => { const { tabListAdd, tabListStatus } = this.props const { tabList } = tabListStatus const userMenu = menuDataSource const menu = this.menuItemFilter(userMenu, `/nav_${param.key}`) let paramTab = { title: menu.name, key: menu.path, queryParam: {}, dataSource: {} } //Judging whether it is a new addition let pushBol = true tabList.map(tab => { if (tab.key === paramTab.key) { pushBol = false paramTab = Object.assign({},paramTab,tab) } return tab }) if (pushBol) { tabList.push(paramTab) } tabListAdd({ tabList, activeTab: paramTab }) this.toPath(`nav_${param.key}`) } // Click Tag onChange = activeKey => { // console.log('....', activeKey) const { tabListStatus, tabListAdd } = this.props const { tabList } = tabListStatus const userMenu = tabList const menu = this.menuChangeFilter(userMenu, activeKey) const paramTab = { ...menu } tabListAdd({ tabList, activeTab: paramTab }) this.toPath(activeKey) } // Close logic remove = targetKey => { let activeKey = this.state.activeTab let panes = this.state.tabList let lastIndex panes.forEach((pane, i) => { if (pane.key === targetKey) { lastIndex = panes.length - 1 === i ? i - 1 : i } }) const panesFilter = panes.filter(pane => pane.key !== targetKey) if (panesFilter.length && activeKey === targetKey) { if (lastIndex >= 0) { activeKey = panesFilter[lastIndex] } else { activeKey = panesFilter[0] } } else { activeKey = null } this.props.tabListAdd({ tabList: panesFilter, activeTab: activeKey }) this.toPath(activeKey !== null ? activeKey.key : '/') } // ... }
2.3 Internal Interaction Logic
- Judging whether there is a new addition
- Operation update onChange, onClear, onSubmit
Use markup symbols, or directly determine whether a key value exists, to send requests. Data Source is used in demo to determine whether requests need to be sent.
componentDidMount() { const { tabListStatus, musicList_query_param, musicList } = this.props const { dataSource } = tabListStatus.activeTab if (!Object.keys(dataSource).length) { musicList(musicList_query_param) } }
Operations update onChange, onClear, onSubmit in addition to these there will be different operations, demo roughly divided these operations, using reducer operations, App.js to monitor operations, change memory, module does not participate in memory changes.
onChange = (tabList, e) => { e.persist() if (!e || !e.target) { return } const { target } = e const operateParam = operateQuery(tabList, { [target.id]: target.type === 'checkbox' ? target.checked : target.value }) this.props.tabListChange(operateParam) }
3. Contrast
Implementation of 3.1 Vue
- Technology stack: vue + vue-router + vuex
- UI Framework: ant-design
Key: keep-alive
3.2 Realization of React
- Technology stack: react + react-router + redux
- UI Framework: ant-design
Key: redux and memory processing
4. Summary
It's certainly faster for Vue to implement the above, but it's also a very interesting thing to control the use of React memory. If the project is large, it's even more interesting.
In fact, this implementation is a bit of a chicken rib, because users do not pay attention to one, closed the page, these Tag s do not exist, no matter what kind of management system, this implementation may be more interesting if cooperated with the background.
Thank @ White Thank you [@colleagues](), they all provide good ideas.
Thank you for reading. The code is rotten. Please spray it lightly.