undefined
undefined

Reputation: 34299

Create an override of a link with reactjs

I would like to make a custom type of link in react which I can use like an a tag but which overrides the onClick to attempt to use a single page app router. It takes a link as props and returns that same link back with the click event overridden.

React.createClass({
    render: function () {
        //super naughty but I cant think of a better way of overloading just this
        var oldOnClick = this.props.a._store.props.onClick;
        this.props.a._store.props.onClick = function () {
            if (oldOnClick) {
                oldOnClick();
            }
            router.navigate(this.props.a._store.props.href);
            return false;//always false as were using a router
        }.bind(this);

        return this.props.a;
    }
});

This works functionally exactly as expected but its super gross and relies on using private properties of the object. What is the 'right' way to do this.

Upvotes: 2

Views: 3386

Answers (1)

Jonny Buchanan
Jonny Buchanan

Reputation: 62813

As documented in Transferring with ... in JSX, you can use the the spread operator enabled by the JSX Transformer's harmony flag to split out any user-defined onClick from the other props, then pass the rest to an <a> using JSX Spread Attributes:

var Link = React.createClass({
  _onClick(e) {
    if (this.props.onClick) {
      this.props.onClick()
    }
    e.preventDefault()
    router.navigate(this.props.href)
  },

  render() {
    var {onClick, ...others} = this.props
    return <a {...others} onClick={this._onClick}>{this.props.children}</a>
  }
})

Alternatively, you can just configure prop overrides manually, e.g. this is how react-router implements its Link component's render(), shallow-copying props then overwriting those which need to be configured/handled by the component:

  render: function () {
    var props = assign({}, this.props, {
      href: this.getHref(),
      className: this.getClassName(),
      onClick: this.handleClick
    });

    return React.DOM.a(props, this.props.children);
  }

Upvotes: 1

Related Questions