React Components Best Practices

Khi bắt sử dụng một thư viện nào đó, bạn phải biết về các best paractices và style để tạo tạo ra những đoạn code clean và ngắn gọn hơn. Dưới đây là một số best practices về React Components

1. Một Component một file

Trong Reactjs cách đợn giản nhất define ra một components là viết 1 hàm javascript

    //This is called functional component because it's literally a function
    function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
    }   

Môt cách nữa là extend component class from React.Component, khi sử dụng cách này nó cung cấp cho chúng ta vòng đời của react.

        class Welcome extends React.Component {
            render() {
                return <h1>Hello, {this.props.name}</h1>;
            }
        }

Và chúng ta nên create mỗi component trong 1 file.

2. Stateless vs Statefull

Bạn nên nhớ, luôn luôn sử dụng Stateless function, trừ khi bạn cần sử dụng vòng đời của Reactjs thì bạn mới sử dụng Statefull

//Stateless component. No need for state, refs or life cycle method
    function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
    }
    
    //Statefull component.
    class Welcome extends React.Component {
        constructor(props) {
            super(props);
            this.state = {'Tehmina'};
        }
        componentDidMount() {
            this.timer = setTimeout(
                () => this.tick(),
            );
        }

        componentWillUnMount() {
            clearTimeout(this.timer); //We should always destroy these kind of handlers
        }

        tick() {
            this.setState({name: 'Faizan'});
        }
        render() {
            return <h1>Hello, {this.state.name}</h1>;
        }
    }

3. Refs

Use ref callback.It's much more declarative

    //Bad
    <Welcome ref="myRef" />

    //Recommended
    <Welcome ref={(ref) => { this.myRef = ref; }} 
    />

4. JSX tags in render method

Khi bạn return từ method render, nếu nó có nhiều hơn một line bạn nên đặt nó trong ().

//Bad
render() {
  return <Welcome className="class">
    		<child />
           </Welcome>;
}
//Recommended
render() {
  return (
    	<Welcome className="class">
    		<child />
        </Welcome>
    );
}
//Or this one also good
render() {
  const child = <child />;
  return <Welcome className="class">{child}</Welcome>;
}

5.Event Handler

Always bind event handler used in render inside constructor or use arrow function because it automatically binds to this context outside function it's being used. Những function envet handler sử dụng trong render nên sử dụng arrow funtion và nên ràng buộc trong constructor. bởi vì nó tự động binds this context.

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.onClickDiv = this.onClickDiv.bind(this);
  }

  onClickDiv(event) {
  }

  render() {
    return (
    	<div onClick={this.onClickDiv} /> //recommended
        <div onClick={ (e) => this.onClickDiv(e) } /> // Not a good practice because when re-render componnent it would create new closure every time
       );
  }
}

6.DefaultProps vs PropTypes

Nếu trong project bạn có sử dụng eslint để check convention thì chắc chắn bạn phải sử dụng DefaultProps vs PropTypes Luôn luôn sử dụng defaultprop cho non-required props .

function Welcome({name, height, children}) {
  return <h1>{name}{height}{children}</h1>;
}
Welcome.propTypes = {
  name: PropTypes.string.isRequired,
    height: PropTypes.number,
    children: PropTypes.node
}
Welcome.defaultProps = {
  height: 0,
    children: null //Null is of type object in javascript with no value
}

7.Higher-Order Components (HOC) vs Mixins

higher-order component trong react là một pattern để reuse component logic. mình có viết một bài về high-order, bạn có thể tham khảm Higher-order components

8.Lists and Keys

Khi bạn thêm ky vào element vào bên trong array, nó sẽ improves redering perfomace.

Key tells react which element is chaged, key nói cho react cái element nào đã thay đổi, được thêm hoắc đã xóa, key luôn là duy nhất và không phải là index của array.

const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);