用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>