標籤:

怎麼樣理解reactjs中組件的反模式?

如題


【一、何為 React 反模式】

反模式當然是指和 React 思想違背的 coding 方式

【二、為什麼會有反模式】

因為 React 的核心是單向數據流,確定性的設計,而這本身與 Javascript 隨處可修改的對象相背。 React 更傾向於 pure 的 render,所以在 coding 的時候因遵守這一原則,否則就是 anti-pattern。

【三、React 中有哪些反模式】

反模式中有社區提的和 React 官方文檔提的一些反模式,先說官方的

1. 不要修改 props (JSX Spread Attributes mutating props is bad)

簡單而言就是在組件中修改 props 的值,因為 React 是單向數據流的模式,在 js 中對象是通過引用傳遞的,修改 props 會破壞單向性和確定性

解決辦法第一是肯定是避免修改,但是多人協作很難保證都遵守這個規則, 更好的方式是可以通過 Immutable.js 來強制避免修改,保證單向數據流。

2. 在 getInitialState 中使用 props (Props in getInitialState Is an Anti-Pattern)

在 getInitialState 中通過 props 來計算 state,anti 的原因是因為破壞了確定性原則,「source of truth」 應該只是來自於一個地方,通過計算 state 過後增加了 truth source。影響編碼邏輯的地方舉例在組件更新props的時候,還需要計算重新計算 state,很容易忘記重計算(通常這種 bug 較難排查)

舉例:

var MessageBox = React.createClass({
getInitialState: function() {
return {nameWithQualifier: "Mr. " + this.props.name};
},

render: function() {
return &{this.state.nameWithQualifier}&;
}
});

ReactDOM.render(&, mountNode);

優化方式:

var MessageBox = React.createClass({
render: function() {
return &{"Mr. " + this.props.name}&;
}
});

ReactDOM.render(&, mountNode);

需要注意的地方是對於一些只在初始化的時候使用的 state 不算 anti, 如:

var Counter = React.createClass({
getInitialState: function() {
// naming it initialX clearly indicates that the only purpose
// of the passed down prop is to initialize something internally
return {count: this.props.initialCount};
},

handleClick: function() {
this.setState({count: this.state.count + 1});
},

render: function() {
return &{this.state.count}&;
}
});

3. 判斷 isMounted (isMounted is an Antipattern)

在 React 中在一個組件 ummount 過後使用 setState 會出現warning提示(通常出現在一些事件註冊回調函數中) ,為了避免 warning 有些人的做法是:

if(this.isMounted()) { // This is bad.
this.setState({...});
}

但是事實上這個是掩耳盜鈴的做法,因為如果出現了錯誤提示就表示在組件 unmount 的時候還有組件的引用,這個時候應該是已經導致了 memory-leak 。所以解決錯誤的正確方法是在 componentWillUnmount 函數中取消監聽:

class MyComponent extends React.Component {
componentDidMount() {
mydatastore.subscribe(this);
}
render() {
...
}
componentWillUnmount() {
mydatastore.unsubscribe(this);
}
}

然後是社區里提的一些反模式 :

1. 使用 mixins (Composition instead of mixins)https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750#.le8yopk2n

2. 在 componentWillMount 使用 setState

3. mutate dom explicitly via Jquery (和 React 的dom衝突 )

4. render with side effects (破壞一致性原則,盡量保證純函數)

5. private states and global events (global Event 增加組件的耦合, private state 影響組件的確定性)

6. 直接修改 state (使用 setState 才會有效果)

GitHub - planningcenter/react-patterns: Mostly reasonable patterns for writing React on Rails 這個 repo 既介紹了一些好的pattern也介紹了一下 anti-pattern:

1. 在 jsx render 中使用複雜條件判斷 -&> compound-conditions

2. 沒把 render 函數中的計算剝離出來 -&> Cached State in render

3. 在 render 函數中判斷是否存在某個屬性 -&> Existence Checking


反模式英文是anti-pattern,也就是說不符合一種框架或思想的模式/風格,但理論上不算錯誤的程序寫法。

React裡面的話,比如說組件裡面放個jQueryDOM操作,就有可能算「反模式」了吧。

現在前端屆浮躁的很,是個程序員,遇見自己看不慣的編程方式,就扣個「反模式」的帽子,我認為除了這個框架的作者或重要貢獻者,是沒有太多資格指責別人的編程方式是「反模式」的。


推薦閱讀:

關於在react中request到底是應該寫在哪裡?
為什麼在知乎上 React 的評價這麼低?
使用react開發,大家使用什麼IDE工具?JSX語法報錯?
問一個react更新State的問題?
在用react的時候老大不讓用jquery,為什麼?

TAG:React |