使用一个组件或模块之前,应当知道它能解决的问题是什么,不能解决的问题是什么。使用的最佳实践是什么?
React 提供的非受控组件 通过 defaultValue
控制表单的默认值。搜索
这是个很棒的方式,因为我们并不需要在任何时候都配置表单控件的 value
和 onChange
。
但是我们自己实现的组件想支持非受控组件就需要自己实现 defaultValue
。比如实现一个点击会递增的 Button
。
<Button value={self.state.value} onChange={function(){...}} />
import ReactDOM from "react-dom"
import React , { Component } from "react"
class Button extends Component {
constructor (props) {
super(props)
const self = this
self.state = {
value: props.defaultValue
}
}
render() {
const self = this
return (
<button
onClick={() => {
if (typeof self.props.onChange === 'function') {
self.props.onChange(self.props.value + 1)
}
else {
self.setState({value: self.state.value + 1})
}
}}
>
{self.props.value || self.state.value}
</button>
)
}
}
class Demo extends Component {
constructor (props) {
super(props)
const self = this
self.state = {
value: 10
}
}
render() {
const self = this
return (
<Button
value={self.state.value}
onChange={function (value) {
self.setState({value: value})
}}
/>
)
}
}
ReactDOM.render(
<Demo />,
document.getElementById('intro-button-demo')
)
<Button defaultValue={20} />
import ReactDOM from "react-dom"
import React , { Component } from "react"
class Button extends Component {
constructor (props) {
super(props)
const self = this
self.state = {
value: props.defaultValue
}
}
render() {
const self = this
return (
<button
onClick={() => {
if (typeof self.props.onChange === 'undefined') {
self.setState({value: self.state.value + 1})
}
else {
self.props.onChange(self.props.value + 1)
}
}}
>
{
typeof self.props.value !== 'undefined'?
self.props.value:
self.state.value
}
</button>
)
}
}
ReactDOM.render(
(
<Button defaultValue={20} />
),
document.getElementById('intro-defaultValue-demo')
)
defaultValue
比较两段代码的区别后可以发现支持 defaultValue
需要加上
self.state = {
value: props.defaultValue
}
props.onChange === undefined
时修改组件内部状态if (typeof self.props.onChange === 'undefined') {
self.setState({value: self.state.value + 1})
}
props.value
不存在时使用组件内部状态{
typeof self.props.value !== 'undefined'?
self.props.value:
self.state.value
}
修改的代码量不大,你甚至可以将第二段代码作为实现 defaultValue
的教程。
但是如果你需要开发很多组件,例如 onface 团队要维护 大量的 react 组件 重复写 defaultValue
代码会变得很枯燥。
有些组件的 输入输出接口比较另类。比如:
输出 onMount
<Count
value={self.state.age}
onMount={self.handleChange}
/>
输入 show
<Tooltip
show={self.state.tip}
onChange={self.handleChange}
/>
标准的输入输出应该是
<input
value={self.state.name}
onChange={self.handleChange}
/>
这些情况下刚才所展示的代码就需要做很多修改。枯燥是不枯燥了,不同组件每次都实现不同的 defaultValue
会变得很繁琐。
Tooltip
的输入是show
是完全合理的,不同于表单控件输入是value
。
使用 react-defaultvalue 能快速优雅的解决这些问题。
/*
<Count
value={self.state.age}
onMount={self.handleChange}
/>
*/
Count = require('react-defaultvalue')(Count, {
output: 'onMount'
})
<Count defaultValue={20} />
/*
<Tooltip
show={self.state.tip}
onChange={self.handleChange}
/>
*/
Tooltip = require('react-defaultvalue')(Tooltip, {
input: 'show'
})
<Tooltip />
<Tooltip defaultShow={true} />