Write less code, do more things!

指引

使用一个组件或模块之前,应当知道它能解决的问题是什么,不能解决的问题是什么。使用的最佳实践是什么?

react-spread-props 专门解决日常开发中传递 props 的同时代理绑定事件的需求。

例如开发一个检测用户点击后递增计数的组件:

计数按钮
import React , { Component } from "react"
class GeneralButton extends Component {
    constructor (props) {
        super(props)
        const self = this
        self.state = {
            count: 0
        }
    }
    render() {
        const self = this
        return (
            <button
                {...self.props}
                onClick={(e) => {
                    if (self.props.onClick) {
                        self.props.onClick(e)
                    }
                    self.setState({
                        count: self.state.count + 1
                    }, function () {
                        if (self.state.count > 3) {
                            if (self.props.onGreaterThree) {
                                self.props.onGreaterThree()
                            }
                        }
                    })
                }}
            >{self.state.count}</button>
        )
    }
}
export default GeneralButton

使用计数按钮

调用计数按钮
import ReactDOM from "react-dom"
import GeneralButton from "./GeneralButton.js"
ReactDOM.render(
    (
        <div>
            <GeneralButton style={{border: '1px solid red'}} />
            传递样式
            <hr/>

            <GeneralButton onClick={(e) => {
                console.log('既可以触发递增,也可以触发用户绑定的 onClick')
            }} />
            绑定 onClick
            <hr/>
            <GeneralButton onGreaterThree={() => {
                console.log('大于3')
            }} />
            大于3时回调
        </div>
    ),
    document.getElementById('intro-genneral-button-node')
)

观察控制台会看见报错

Warning: Unknown event handler property `onGreaterThree`. It will be ignored.

因为传递 props 的同时代理用户绑定事件的实现代码是:

{...self.props}
onClick={(e) => {
    if (self.props.onClick) {
        self.props.onClick(e)
    }
    self.setState({
        count: self.state.count + 1
    }, function () {
        if (self.state.count > 3) {
            if (self.props.onGreaterThree) {
                self.props.onGreaterThree()
            }
        }
    })
}}

因为 {...self.props} 传递了 onGreaterThree 所以会报错。想要不传递 onGreaterThree 就要过滤 onGreaterThree

var spreadProps = Object.assign({}, self.props.props)
var ignoreProps = ['onGreaterThree']
Object.keys(spreadProps).filter(function (key) {
    return ignoreProps.includes(key)
})
// 然后传递 spreadProps
{...spreadProps}

至此实现了传递 props 的同时代理绑定事件的需求。

因为开发组件过程中需要做 react spread props 的操作太多了,所以将实现过程封装成函数能提高开发效率。

使用 react-spread-props 的按钮
import React , { Component } from "react"
import spreadProps from "react-spread-props"
class Button extends Component {
    constructor (props) {
        super(props)
        const self = this
        self.state = {
            count: 0
        }
    }
    handleClickButton = (e) => {
        self.setState({
            count: self.state.count + 1
        }, function () {
            if (self.state.count > 3) {
                if (self.props.onGreaterThree) {
                    self.props.onGreaterThree()
                }
            }
        })
    }
    render() {
        const self = this
        let domProps = spreadProps(
            self.props,
            { onClick: handleClickButton }
        )
        return (
            <button {...domProps} >{self.state.count}</button>
        )
    }
}
export default Button

语法: spreadProps(props, proxyProps)

实现功能与 <GeneralButton /> 但代码更少更易读。(因为 onGreaterThree 不属于 DOM 事件,所以会被自动过滤)

style&className

props.styleprops.className 将与 proxyProps.styleproxyProps.className 自动合并。

示例代码

stopTrigger

你还可以在 proxyProps.onClick 中控制 props.onClick 触发条件。

let domProps = spreadProps(
    self.props,
    {
        onClick: function (){
            // do somethings
            this.stopTrigger()
        }
    }
)
<Button onClick={() => {
    console.log('因为 this.stopTrigger 用户绑定的 onClick 将不会被触发')
}} />

示例代码

新的属性

万一 react-spread-props 错误的将一些新的 DOM 属性过滤了请及时通知我们

你也可以先通过单独传递的方式解决这种意外情况。

<button
    {...domProps}
    futureAttr="Future unpredictable dom attributes"
>
</button>
Github
react-spread-props - 项目源码
相关站点
component-spec - 组件规范
module - 开源项目脚手架
onface.live - 资源集合