Skip to content

Instantly share code, notes, and snippets.

@jean182
Last active July 28, 2020 03:18
Show Gist options
  • Save jean182/c05f916c43195e85280538ace021c8ee to your computer and use it in GitHub Desktop.
Save jean182/c05f916c43195e85280538ace021c8ee to your computer and use it in GitHub Desktop.

Ideas

  1. Prefer the usage of native methods, don't rely too much on lodash. Examples:

    1. We tend to over use isEmpty and there're many native ways to do it:
     import { isEmpty } from "lodash-es";
    
     /* When an array is present or does not have values */
     const emptyArr = [];
     console.log(!isEmpty(emptyArr))
     // output: false
    
     // same check using native methods
     console.log(Array.isArray(emptyArr) && emptyArr.length > 0)
     // output: false
    
     /* When a string is empty */
     console.log(isEmpty("Hola"))
     // output: false
    
     // same check using native methods
     console.log(!!"Hi")
     // output: true
    
     /* When a object property is present or not */
     const obj = { name: "Jean" };
     console.log(!isEmpty(obj.surName));
    // output: false
    
    // same check using native methods
    console.log(!!obj.surname)
    // output: false
    
    /*
     Checking an empty object is a bit harder though, so I would reccomend using the isEmpty method
     If you want to do it yourself:
     => isEmpty for objects
     Link: https://coderwall.com/p/_g3x9q/how-to-check-if-javascript-object-is-empty
    */

    I would say in most of the cases that we think isEmpty is required, we should rethink how are we passing the props, how do we use the PropTypes and how we can improve the code to avoid the use of it (not saying we should not use it, but be smart on how to use it).

  2. Don't pass the whole object as a prop if you're only using a few attributes of it Examples:

 const visualization = {
   // Lot of props
   values: [1, 2, 3]
 }
 // Incorrect
  <Score visualization={visualization} />
  // Correct
  const score = visualization.values[0] // Just an example, please validate if doing something like this;
  <Score scoreValue={score} />
  1. Avoid using PropTypes.oneOfType([PropTypes.object]), explicitly add all the attributes that will be used, this can be avoided if you pass props using rule number 2, but if you need to pass the full object, use this rule instead. Example:

      const Person = ({ person }) => {
        const { id, name } = person;
        return <div>{name} - {id}</div>
      }
    
     // Wrong
      Person.propTypes = {
         person: PropTypes.oneOfType([PropTypes.object]).isRequired,
       };
    
       // Good (Help us to check which properties are needed for the component to work)
       Person.propTypes = {
         person: PropTypes.shape({
           id: PropTypes.number,
           name: PropTypes.string
         }).isRequired,
       };
      }),
  2. Think twice when connecting a component to the redux store(You might have the prop in the parent or there's no need to connect it at all).

  3. Connected components don't require a default prop declaration(for connected values), they will always have the values set in the redux state so you can set those values as required props in the component. Example:

 const mapStateToProps = state => ({
    loading: state.reducer.loading,
  });
  // Assuming that loading is a boolean value.
  YourComponent.propTypes = {
    loading: PropTypes.bool.isRequired
  };
  export default connect(mapStateToProps)(YourComponent);
  1. Make components as dumb as possible: Examples:

      // Good
      const Button = ({ content, onClick, btnStyles }) => (
        <button className={btnStyles} onClick={onClick}>
         {content}
        </button>
      );
    
      // Bad
      const Button = ({ content, onClick, btnStyles }) => (
        <div className="viz container">
         <div className="btn-container">
           <button className={btnStyles} onClick={onClick}>
             {content}
           </button>
         </div>
        </div>
      )

    The second example is tied to the div classNames, so the classes will need to be modified in every component where we want to put the button, we want this component to be easy to reuse and we need to make it pretty dumb, so the first option is better cause it will work on any given container.

  2. Prefer React.Fragment instead of </> Open to discussion Examples:

     <React.Fragment>
       <div>Hola</div>
     </React.Fragment>
    
     <>
       <div>Hola</div>
     </>
  3. Prefer destructuring in the function parameters section instead of inside the function Open to discussion Examples:

     const Person = ({ name }) => <div>{name}</div>
    
     const Person = (props) => {
       const { name } = props;
       return <div>{name}</div>
     }
  4. Prefer the shorthand syntax of the arrow function if you're not doing anything before the return statement Examples:

     // good
     const sum = (a, b) => a + b;
     // Bad
     const sum = (a, b) => {
       return a + b;
     };
     // Good
     const weirdSum = (a,b) => {
       const firstNum = Number(a) * 100 + 50;
       const secondNum = Number(b) * 300 + 100;
       return firstNum + secondNum;
     }
  5. Avoid mutating stuff unless is intended for some reason, react and redux will have strange behaviors if you mutate the state.

  6. Keep in mind accesibility when working with custom components that act, but are not buttons, links or any other interactive html element. https://reactjs.org/docs/accessibility.html. The HierarchyBreadcrumb component is a good example of a component that uses a <span> tag that acts like a button

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment