How front-end engineers continue to maintain enthusiasm

For one thing, often repeated, then it is easy to get bored, to feel bored, I lost the original enthusiasm.

  • Endless business needs, day after day, I felt tedious work, all manual labor;
  • c end do more, feel no challenge business logic, boring, demanding design, particularly annoying;
  • b-side to do more, feel every day to write platform, every day against tasteless data, no chance to play with cool special effects;
  • Construction technology to do more, to do their own things looked tired;
  • At some fancy stuff, and having no relevance to the work content;
  • Want about the latest technology, but the project for historical reasons and often inaccessible ......

Naturally, I lost the original enthusiasm, can not find a sense of accomplishment, and even suspect that he is not not suitable for front-end, is not it a career change, is not to change jobs?

Avoid repeating the same way to do the same thing

If you have the same attitude to do the same thing, it is easy to feel bored, no sense of accomplishment. So it is necessary to enhance the efficiency of doing the same thing, back faster and faster to complete, have seen their progress every day, there will be a natural enthusiasm

Streamline the code, improve code quality

When you want to copy, you may want to look at where the package, where logic to pull away, where you want to reuse code

Do not let a presence of almost all the same code duplication

Getting all the time, you might have written code like this:

<a>首页</a>
<a>关于我们</a>
<a>合作</a>
<a>加入我们</a>

Later found, vue be v-for, react can map, native fragment which can be inserted into the final loop disposable append.
Quite obvious that we can find, if less obvious but also reuse of how I found it? Again, when you copy the code you can reuse. For antd Form a common scenario:

<Form>
  <Item label="名称">
  {getFieldDecorator('name', {
    rules: [{
      required: true,
      message: '请输入名称',
    }],
  })(<Input />)}
  </Item>
  <Item label="描述">
  {getFieldDecorator('desc', {
    rules: [{
      required: true,
      message: '请输入描述',
    }],
  })(<Input />)}
  </Item>
  <Item label="类型">
  {getFieldDecorator('type', {
    rules: [{
      required: true,
      message: '请选择类型',
    }],
  })(<Checkbox />)}
  </Item>
</Form>

Routine is the same, the structure is the same, then we maintain a configuration object to maintain this form:

const items = [
  {
    label: '名称',
    key: 'name',
    decorator: {
      rules: [{
      required: true,
      message: '请输入名称',
    }],
    },
    component: <Input />
  },
  // ...
]

Another example of a very long if, back in the front-end processing error code, common piece of code:

// before
if (type === 1) {
  console.log('add')
} else if (type === 2) {
  console.log('delete')
} else if (type === 3) {
  console.log('edit')
} else {
  console.log('get')
}

// after
const MAP = {
  1: 'add',
  2: 'delete',
  3: 'edit',
  4: 'get',
}
console.log(MAP[type])

Be reduced by arranging the object code duplication, rendering cycle

There must be a kind of "too lazy to write the code" mentality

For example, the action type redux

const FETCH_LIST = 'FETCH_LIST'
const FETCH_LIST_SUCCESS = 'FETCH_LIST_SUCCESS'
const FETCH_LIST_FAILED = 'FETCH_LIST_FAILED'
const FETCH_USERINFO = 'FETCH_USERINFO'
const FETCH_USERINFO_SUCCESS = 'FETCH_USERINFO_SUCCESS'
const FETCH_USERINFO_ERROR = 'FETCH_USERINFO_ERROR'

Very neat and looks very comfortable in the code, but they all have in common, asynchronous request, the request, the request is successful, the request failed type. Every time new, we first came here three lines of copy, and then change to change. Since almost all, we can write a type generators:

function actionGenerator(k = '') {
  const key = k.toUpperCase()
  return {
    ...(k
      ? {
        [`FETCH_${key}`]: `FETCH_${key}`,
        [`FETCH_${key}_SUCCESS`]: `FETCH_${key}_SUCCESS`,
        [`FETCH_${key}_ERROR`]: `FETCH_${key}_ERROR`,
      }
      : {}),
  };
}
// 从此以后,action_type代码行数大大减少

Another example of a function which is repeated assignment of an object:

// before
obj.a = 1
obj.b = 2
obj.c = 5
// after
const newVals = {
  a: 1,
  b: 2,
  c: 5
}
// 如果业务里面的obj很依赖原本引用,不能改变原对象
Object.keys(newVals).forEach(key => {
  obj[key] = newVals[key]
})
// 如果业务里面的obj不依赖原本引用,可以改变原对象
obj = { ...obj, ...newVals}
// 以后要改什么,我只要去改一行newVals就可以

Another example page copy, we can carry out alone to a unified configuration file which, after easily modified

<header>练习不足两年半的练习生</header>
<section>我只是一个练习生</section>
<ul>
  <li>唱</li>
  <li>跳</li>
  <li>rap</li>
</ul>
<footer>联系方式:000</footer>
const CONSTANT = {
  title: '练习不足两年半的练习生',
  desc: '我只是一个练习生',
  hobbies: ['唱', '跳', 'rap'],
  tel: '000'
}

<header>{CONSTANT.title}</header>
<section>{CONSTANT.desc}</section>
<ul>
  {
    CONSTANT.hobbies.map((hobby, i) => <li key={i}>{hobby}</li>)
  }
</ul>
<footer>联系方式:{CONSTANT.tel}</footer>

This is a look as if to write more code becomes complicated. In general, this is not required. For operational needs, this program can be changed at any time to deal with that change is necessary to change the copy is easy, and does not need to care about page structure, you do not have to copy html inside to find where a file directly write such things put CONSTANT of. But this object also can be reused, there will be the kind of "change of change copy dozens of pages" of the situation.
There is also a scene, we usually might have written a lot of code like this:

function sayHi(name, word) {
  console.log(`${name}: ${word}`)
}
const aSayHi = () => sayHi('a', 'hi')
const aSayGoodbye = () => sayHi('a', 'goodbye')
const aSayFuck = () => sayHi('a', 'fuck')

Of course, this is a very simple scenario, if the function argument passed sayHi there are many, but there are a number of repeat words, the code redundancy. At this time, we need to use partial function optimization:

const aSay = (name) => sayHi('a', name)
const aSayHi = () => aSay('hi')
const aSayGoodbye = () => aSay('goodbye')
const aSayFuck = () => aSay('fuck')

Ternary expressions are used up a short circuit, a few examples

// before
if (type === true) {
  value = 1
} else {
  value = 2
}
//after
value = type ? 1 : 2

// before
if (type === DEL) {
  this.delateData(id)
} else {
  this.addData(id)
}
// after
this[type === DEL ? 'delateData' : 'addData'](id)
// or
;(type === DEL ? this.delateData : this.addData)(id)

// before
if (!arr) {
  arr = []
}
arr.push(item)
// after 这个属于eslint不建议的一种
;(arr || (arr = [])).push(item)

// before
if (a) {
  return C
}
// after
return a && C

Finally an example, such a repeated key assignment process can be simplified with the variable key

switch(key) {
  case 'a':
  return { a: newVal }
  case 'b':
  return { b: newVal }
  case 'c':
  return { c: newVal }
}
// after
return { [key]: newVal }

however, it was more than familiar with the matter, how well written the code must also write comments. The core algorithm, public assemblies, public functions are especially needed Notes

/**
 * 创建树状组织架构
 * @param {Object} orgs
 * @param {Array} [parent=[]]
 * @param {Boolean} check 是否需要校验
 */

Summary: Short Code no duplicates, and watching themselves not greasy; detached logic functions encapsulate common invisible code quality improve. Finally benefits that accelerate the development efficiency, but also enhance the development experience and accomplishment: "Finally not every copy, and looked at his hand and simply elegant code, want to demand more and more of the"

How to make operational requirements are not boring

Most companies are based on business demand-driven, iterative requirements in addition to the flagship product of his home, the other is usually operational needs as an auxiliary. Class operational requirements, generally have a short-lived, high-frequency characteristics have a deadline.
One operator activities, there may be a variety of modes, a variety of display layouts, a variety of logic, random combination of product operations, according to data adjusted to find the best solution, which is the operational play scenarios --ab test.
Some people Faced with this situation, always sigh: demand has also changed, and nothing has changed with every day, how they change back, you happy enough. In fact, this situation, we just give yourself a good plan way ahead, behind really free to change, do not even need to develop basic
We start with a simple example of a user's information page:

render() {
  const { name, score } = this.state.info
  return (
    <main>
      <header>{name}</header>
      分数:<section>{score}</section>
    </main>
  )
}

Increase adaptation layer
We try not to move the core logic code public, do not say "just add if it." The introduction of new code, may introduce other bug (one of the common illusion: I added a line or two, will not cause bug), there are certain risks.
Back to the topic, if you suddenly say this event to pull another game scores directly to the requested change, and then put all the components of the field changed, of course, it is a method. If you change soon finished, go back and change have to say, it is not vomiting blood. Clearly we need an adaptation layer:

function adapter(response, info) {
  return Object.keys(newConf).reduce((res, key) => {
    res[key] = response[newConf[key]]
    return res
  }, {})
}
// before
function fetchA() {
  return request('/a')
}
fetchA.then(res => {
  this.setState({
    info: { name: res.nickname, score: res.counts }
  })
})

// after 直接修改原请求函数
function fetchA() {
  return request('/a').then(res => {
    // 把适配后的结果返回,对外使用的时候不变
    return adapter(res, {
      name: 'nickname',
      score: 'counts'
    })
  })
}

We adapted to focus together, each to be changed, as long as the adaptation layer to change here, can change request interface. Of course, back then, if all unity is the best, but there are historical reasons not changed on a whim of.

If a lot of change to change the interface to do: expand?
At this point, we need to maintain a configuration table, save a request and adaptation objects, rather than directly to get rid of the previous code

const cgiMAp = {
  '/a': {
    name: 'nickname',
    score: 'counts'
  },
  // ...
}

By reading this configuration, a request read logic function inside the package, can be adapted to all interfaces. If you later change a data sources, that address the needs of the speed of light

function reqGenerator(cfg) {
  return Object.keys(cfg).reduce((res, key) => {
    res[key.slice(1)] = () => request(key).then(r => adapter(r, cfg[key]))
    return res
  }, {})
}
const reqs = reqGenerator(cgiMAp)
reqs.a()

Components of strict compliance

For example in front of the user's information page, if the user information page requires more content to fill it, if you do not want to show the score it?

This case, first and confirm the product side, what is the future must be and what will become. Will be changeable part, we directly use the content time coming:

class App extends Component {
  // ...
  render() {
    const { name, score } = this.state.info
    return (
      <main>
        <header>{name}</header>
        <section>{this.props.children}</section>
        分数:<section>{score}</section>
      </main>
    )
  }
}

This way, as long as the upper component wrap personalization component content on ok

<App>
  <section>我只是一个练习生</section>
  <ul>
    <li>唱</li>
    <li>跳</li>
    <li>rap</li>
  </ul>
</App>

Of course, things are certainly not as simple as people are fickle, and now you say that the title will never change, and turned to change it to you: If you did not attend, then another gray display prompts the user if a high score and give him the title plus a subscript, if you charge money, the title change skin

We still change as little as possible to keep the core principles of logic, a first header portion extraction components:

const [IS_NO_JOIN, IS_PAY, IS_SCORE_HIGH] = [1, 2, 3]
const MAP = {
  [IS_NO_JOIN]: 'no-join',
  [IS_PAY]: 'has-pay',
  [IS_SCORE_HIGH]: 'high-score',
}
function Header(props) {
  const [type, setType] = useState('normal')
  useEffect(() => {
    // 用名字获取用户身份
    requestTypeByName(props.children).then(res => {
      setType(res.type)
    })
  }, [])
  return (
    <header
      className={classnames(MAP[type])}
    >
      {props.children}
    </header>
  )
}

The core logic is not moving, is not rendered movable structure and sequence. More customization features, from the top of our parent component control, rendering control logic, display components, copywriting and so on display, the upper parent component assembled good, passing through props core components. This process is the core rendering logic such as writing before a colleague. Header components are written in a, b colleague is not responsible for this, but b is the demand of developers, so should render good posture adjustment, adaptation, injected into a colleague wrote to the core logic components. The final performance is give control to the b, b to make change, this way is less invasive, low risk, and strong expansion of a scheme.

"The success dumped a pot", a document the training and preparation b, and b after completion logical explanation laughs off work - this is a more elegant and secure solutions, we all understand

Anti-forward point of view, if to make a change (assuming that the core module is a huge complex and can not live only by the quick start to a hold of):

// 加样式n行
// 加处理state逻辑、加业务逻辑而且不能影响原有逻辑,改得小心翼翼
// 改字段来适配,又几行
  render() {
    const { name, score } = this.state.info
    return (
      <main>
        <header className="xxx">{name}</header>
        <section>{this.props.children}</section>
        分数:<section>{score}</section>
      </main>
    )
  }
// after coding: mmp,b的需求为什么要我出来帮忙,还要我从头开始看需求并了解需求

Change over, on the line, the operator suddenly said back side, or to find a heart XXX .... In this case the shaded area

Operations configure the interface
previous example, we are doing very little change is complete. Of course a change each digit to change words, the front end will be released, this is not an elegant solution. So the final solution should be, this part of the configuration pulled out, so that one operator on the platform configuration, front-end interface to read through the configuration of the platform back to render the page. Operators need to change, we just need to put on the platform configuration modifications.

// 让配置写在一个可视化配置平台上
// const cgiMAp = {
//   '/a': {
//     name: 'nickname',
//     score: 'counts'
//   },
//   // ...
// }
function reqGenerator(cfg) {
  return Object.keys(cfg).reduce((res, key) => {
    res[key.slice(1)] = () => request(key).then(r => adapter(r, cfg[key]))
    return res
  }, {})
}
request('/config').then(res => {
  const reqs = reqGenerator(res.cgiMAp)
  reqs.a()
})

But also consider caching, disaster recovery, improve the look of the page usability, accessibility:

If the interface is hung up, how to enhance the user experience of
how to make a page in the hands, such as monitoring, Buried
how to do robust page, and can withstand the ravages of indiscriminate operation of various machines and users

At last

Lower the front label, no matter what is on their own is a kind of growth, in addition to technology, more of a variety of soft skills, methodology, way of thinking. Only to find out the social, coding is perhaps the easiest part of life

Guess you like

Origin blog.51cto.com/14484771/2433702