redux 官方示例 todomvc 兩個(gè)警告修復(fù)

題外話:
本人有輕度代碼潔癖,只要有警告,我會(huì)認(rèn)為代碼還有需要完善的地方,只要有時(shí)間我就會(huì)著手去解決它,去了解其背后的原因,了解為什么會(huì)發(fā)出警告,以及解決方案是什么,最終消除這些影響代碼質(zhì)量的“隱患”。
通過(guò)解決這類問(wèn)題,會(huì)讓自己對(duì)相關(guān)代碼的理解更加深入,做到知其然,并且知其所以然,同時(shí),能夠讓自己對(duì)相關(guān)知識(shí)點(diǎn)印象深刻。

兩個(gè)警告相關(guān)的 PR

備注:PR 合并之后,最新版已經(jīng)沒(méi)有這兩個(gè)警告了

官方 todomvc 示例源碼

其實(shí)改動(dòng)很小,主要看解決思路和理解相關(guān)的知識(shí)點(diǎn)。

兩個(gè)大大的紅色警告

examples/todomvc/src/components/TodoTextInput.js

完整警告信息如下:

Warning: Received the string `true` for the boolean attribute `autoFocus`. Although this works, 
it will not work as expected if you pass the string "false". Did you mean autoFocus={true}?
    in input (at TodoTextInput.js:40)
    in TodoTextInput (at Header.js:8)
    in header (at Header.js:6)
    in Header (created by Connect(Header))
    in Connect(Header) (at App.js:7)
    in div (at App.js:6)
    in App (at src/index.js:13)
    in Provider (at src/index.js:12)

解決

上面的提示信息,其實(shí)已經(jīng)非常友好了,看重點(diǎn):Did you mean autoFocus={true}?
看一下報(bào)錯(cuò)的地方的源碼(TodoTextInput.js:40

  <input className={
    classnames({
      edit: this.props.editing,
      'new-todo': this.props.newTodo
    })}
    type="text"
    placeholder={this.props.placeholder}
    autoFocus="true"
    value={this.state.text}
    onBlur={this.handleBlur}
    onChange={this.handleChange}
    onKeyDown={this.handleSubmit} />

根據(jù)友好的提示信息,將上面的 autoFocus="true" 改為 autoFocus={true} 即可。

examples/todomvc/src/components/MainSection.js

完整警告信息如下:

index.js:1452 Warning: Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler. 
This will render a read-only field. 
If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.
    in input (at MainSection.js:12)
    in span (at MainSection.js:11)
    in section (at MainSection.js:8)
    in MainSection (created by Connect(MainSection))
    in Connect(MainSection) (at App.js:8)
    in div (at App.js:6)
    in App (at src/index.js:13)
    in Provider (at src/index.js:12)

看一下報(bào)錯(cuò)的地方的源碼(MainSection.js:12

  <input
    className="toggle-all"
    type="checkbox"
    checked={completedCount === todosCount}
  />

從下面的提示信息看

You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field.

我的理解是:設(shè)置了 checked 屬性,但是又沒(méi)有提供 onChange 事件來(lái)更新它,那么,將會(huì)自動(dòng)為其設(shè)置一個(gè) read-only 屬性。
將上面的代碼,去掉 className 屬性,如下:

  <input
    type="checkbox"
    checked={completedCount === todosCount}
  />

再看界面,這時(shí)候,一個(gè)可以看到是否選中狀態(tài)的復(fù)選框出現(xiàn)了,它確實(shí)是只讀的,點(diǎn)擊沒(méi)有反應(yīng),當(dāng)所有待辦事項(xiàng)變成完成狀態(tài)時(shí),該 checkbox 會(huì)被設(shè)置為選中狀態(tài),否則為非選中狀態(tài)。
再看后面的提示:

If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly` 

我的理解是:如果該 checkbox 是可變的,那么,請(qǐng)為其設(shè)置一個(gè)默認(rèn)值,否則,要么設(shè)置 onChange 事件,要么設(shè)置 readOnly 屬性。
設(shè)置默認(rèn)值,例如設(shè)置默認(rèn)選中,可以這樣:

  <input
    type="checkbox"
    defaultChecked={true}
  />

如果為其設(shè)置默認(rèn)值 defaultChecked,但不動(dòng)態(tài)設(shè)置 checked 屬性,是不會(huì)有上面的警告的,但我們需要?jiǎng)討B(tài)為其設(shè)置 checked 屬性,這樣在界面上能看出來(lái)是否為全部選中狀態(tài)(向下的箭頭顏色有差別,更詳細(xì)的,請(qǐng)運(yùn)行起來(lái)查看實(shí)際效果)。

很明顯,如果要為其設(shè)置 checked 屬性,設(shè)置 defaultChecked 是沒(méi)有意義的(即使設(shè)置了,也還是會(huì)報(bào)同樣的警告)。
所以,從提示信息看上,為了消除這個(gè)警告,有兩種解決辦法:

  1. 設(shè)置 readOnly 屬性。
      <input
        type="checkbox"
        defaultChecked={completedCount === todosCount}
        readOnly
      />
    
  2. 設(shè)置一個(gè) onChange 事件,哪怕是一個(gè)什么也不做的“空”事件。
      <input
        type="checkbox"
        defaultChecked={completedCount === todosCount}
        onChange={()=>{}}
      />
    

對(duì)于這個(gè)例子,設(shè)置 readOnly 是最好的方案,本來(lái)也是需要只讀的嘛。設(shè)置“空”事件有點(diǎn)莫名其妙。

解讀第二個(gè)警告

至于為什么 react 會(huì)有這樣的檢查,stackoverflow.com 網(wǎng)站上有一個(gè)網(wǎng)友的回答,我認(rèn)為是比較貼切的,摘錄如下:

Controlled Components

Attributes needed:

  1. value - <input> (not checkbox or radio), <select>, <textbox> or checked for (checkbox or radio).
  2. onChange
  • React handles the condition of the element by updating the value or checked attribute (depending on the element) from the props or the state.
  • We need to notify react when we make a change, like inserting data, or checking the box,
  • so react can update the element's condition when it rerenders the component.
  • To do so, we must include an onChange handler, in which we will update the state or notify the component's parent, so it will update the props.
<input
  type="checkbox"
  checked={ this.props.checked }
  onChange={ this.checkboxHandler } 
/>

Uncontrolled Components

Attributes needed:

defaultValue - <input> (not checkbox or radio), <select>, <textbox> or defaultChecked for (checkbox or radio).

React sets the initial value using defaultValue or defaultChecked, and the update of the element's state is controlled by the user, usually via the DOM using refs.

<input
  type="checkbox"
  defaultChecked={ this.props.checked } 
/>

擴(kuò)展閱讀

是有關(guān)可控組件和非可控組件的。

關(guān)于作者

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • It's a common pattern in React to wrap a component in an ...
    jplyue閱讀 3,379評(píng)論 0 2
  • 原教程內(nèi)容詳見(jiàn)精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過(guò)程中的一些閱讀筆記,個(gè)人覺(jué)得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,931評(píng)論 1 18
  • DataBinding函數(shù)庫(kù)的引入方式: DataBinding的布局文件 以layout為根布局標(biāo)簽,包含dat...
    wanTag閱讀 1,316評(píng)論 0 1
  • 9月15日 陽(yáng)光先鋒 第47天分享 周末驅(qū)車回鄉(xiāng)鎮(zhèn),經(jīng)過(guò)童年時(shí)代的竹林,童年時(shí)代的一幕幕在腦海閃過(guò)。還記得...
    竹馬哥哥閱讀 191評(píng)論 0 0

友情鏈接更多精彩內(nèi)容