用React寫一個小組件的時候遇到了一個問題,記錄下來,暫時的html代碼如下
<div className="switch"> <input type="radio" name="switch" id="on" checked/> <label htmlFor="on">on</label>
<input type="radio" name="switch" id="off"/> <label htmlFor="off">off</label> </div>
運行時會waring,主要內容為
You provided a `checked` prop to a form field without an `onChange` handler.
並且點擊兩個label都沒有反應了,仔細查看一下報錯信息,大致是說默認checked的單選框如果沒有綁定onChange事件,就會被框架渲染為只讀(read-only),解決辦法
1: 為每個input都添加onChange事件,對按鈕改變事件做出響應,這樣React就不會把它渲染為只讀控件
2: 使用React提供的方式設置默認值 ,即 defaultChecked={true} (顯然這個更友好)
P.S. 在寫CSS的時候遇到了兩個label之間始終有間隙的問題,改display:inline; 改margin/padding都沒用 ,最后還是在公司前輩小張哥的提醒下才想到了是元素節點之間默認渲染的文本節點的字體大小引發的問題,解決辦法也有兩個
1.在兩個label之間用注釋節點填充
<div className="switch"> <input type="radio" name="switch" id="on" checked/> <input type="radio" name="switch" id="off"/> <label htmlFor="on">on</label><!-- --><label htmlFor="off">off</label> </div>
2.將父元素的font-size置為0,再在需要的位置重新設置font-size,即
.switch{ font-size: 0; } .switch label{ font-size: 20px; }
以前總覺得博客要寫一些高大上的東西,而自己技術水平又達不到,所以總是沒東西可寫。像文本節點這個問題其實以前也遇到過,但是當時覺得是個小問題而已,沒必要專門寫一篇博客,結果這次遇到一時就沒想起來,還是耽誤了一些時間,看來以后遇到問題還是應該不分大小,多記錄總結一下才對。
說了這么多,來看一看這個小東西吧
另外,覺得組件的設計挺好玩的,React還沒實現好,先把html代碼貼出來分享給大家,有興趣可以關注我的Github https://github.com/iny7 喲
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Switch</title> <style> .switch{ width: 100px; height: 40px; line-height: 40px; box-shadow: 1px 1px 2px #F60,1px 1px #CCC inset; perspective:400px; transform-style: preserve-3d; transform-origin: 50% 100%; transform: rotateX(40deg); border-radius: 5px; background-color: #AF6432; font-size: 0; } .switch::after{ content:''; clear: both; } .switch input{ display: none; } .switch label{ display: inline-block; background-color: #CCC; height: 100%; width:50%; font-size: 20px; font-weight: bold; /*line-height: 30px;*/ text-align: center; transform-style: preserve-3d; /*文字不可選擇*/ -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; -khtml-user-select: none; user-select: none; } .switch input:checked+label{ background-color: #F60; } .switch label:first-of-type{ border-radius: 5px 0 0 5px; } .switch label:last-of-type{ border-radius: 0 5px 5px 0; } .switch input:checked+label:first-of-type{ width:49%; margin-left: 1%; transform-origin: 100% 50%; transform: rotateY(12deg); } .switch input:checked+label:last-of-type{ transform-origin: 0% 50%; transform: rotateY(-12deg); } </style> </head> <body> <div class="switch"> <input type="radio" name="test" id="on" checked/> <label for="on">on</label> <input type="radio" name="test" id="off" /> <label for="off">off</label> </div> </body> </html>