Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the React equivalent of an Angular directive that only works on attributes?

For example you could have a directive in angular like so:

angular.module('app') .directive('classy', function() {   return {     restrict: 'A',     link: function($scope, $el) {        $el.addClass('stay-classy');     }   } } 

And implement like so:

<div classy></div> 

There doesn't seem to be an equivalent in React that I've seen after reading through most the docs and googling. I was hoping for something like:

... render: function() {   return (      <MyComponent classy></MyComponent>   ); } 

Is there something like that possible that I've been missing? Is there a different yet functionally similar equivalent? Or maybe this question just shows that I'm missing some part of the "React way" and I shouldn't ever want to do this. Thanks!

like image 266
ccnokes Avatar asked May 23 '15 03:05

ccnokes


People also ask

What is attribute directive in Angular?

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive.

Is there directives in React?

react-directive is a library for creating conditional or listing directives in a react app. It takes a lot of inspiration from Vue. js' conditional and listing directives such as v-if and v-for. Its two main purposes are listed below.

What are the three types of directives in Angular?

The three types of directives in Angular are attribute directives, structural directives, and components.

Is there dependency injection in React?

Dependency Injection is being used by many popular libraries in the React ecosystem, such as React Router and Redux. Additionally, React also has direct support for dependency injection.


1 Answers

It will be helpful to consider what Angular and React are each doing "behind the scenes."

In your Angular example, when you write <div classy/></div> you're saying "render a DIV element and then attach to it the behaviors defined by the classy directive.

In your React example, when you write <MyComponent classy></MyComponent>, you're saying, "create an instance of MyComponent and pass it the props { classy: true }. The transpiler (Babel or whathaveyou) will turn it into the following JavaScript:

React.createElement(MyComponent, { classy: true }); 

So the answer to your question is that you can't write <MyComponent classy></MyComponent> because MyComponent component doesn't know what to do with the classy prop. In React, you might write something like this instead:

class ClassyDiv extends React.Component {   render() {     const { className, ...rest } = this.props;     return <div className={`${className || ''} stay-classy`} {...rest}/>;   } } 

This works because we know the React.DOM.div component (like most DOM components) knows what to do with the className prop.

Since React 0.14 we can express something like this more simply, as a "pure" stateless functional component, i.e. a function that accepts props and returns the rendered result:

function AlsoClassyDiv(props) {   const { className, ...rest } = props;   return <div className={`${className || ''} stay-classy`} {...rest}/>; }; 

You can see both approaches in action in the below snippet.

class ClassyDiv extends React.Component {    render() {      const { className, ...rest } = this.props;      return <div className={`${className || ''} stay-classy`} {...rest}/>;    }  }    function AlsoClassyDiv({ className, ...props }) {    return <div className={`${className || ''} stay-classy`} {...props}/>;  };    ReactDOM.render(    <div id="container">      <div>Regular div</div>      <ClassyDiv>ClassyDiv!</ClassyDiv>      <AlsoClassyDiv>AlsoClassyDiv!</AlsoClassyDiv>    </div>,    document.body  );
.stay-classy { font: bold 3em Helvetica; text-shadow: 4px 4px 2px #aaa; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
like image 155
Jordan Running Avatar answered Sep 20 '22 21:09

Jordan Running