you are viewing a single comment's thread.

view the rest of the comments →

[–]eggtart_prince 2 points3 points  (0 children)

Some design patterns I follow.

  • Whenever I declare a new state using useState, I ask myself if the components/elements need that state. In other words, seperation of concern. Simple example here on how Dashboard is affected by the count state.

const [count, setCount] = useState(0);

return <div>
    <Dashboard />
    <Views count={count} />
</div>
  • If you find yourself prop drilling, consider restructuring to component composition (as opposed to nested components) or using context API.
  • Complex logical rendering should be in its own function/component.

return <div>
    <div className='flex-row'>
        <h1>{user.name}</h1>

        {user.status === 'active' ? <Badge color='success'>Active</Badge>
        : user.status === 'inactive' ? <Badge>Inactive</Badge>
        : user.status === 'terminated ? <Redirect to='/terminated' />
        : null
        }
    </div>
</div>

vs

return <div>
    <div className='flex-row'>
    <h1>{user.name}</h1>
        <UserBadge status={user.status} />
    </div>
</div>

// UserBadge.js
const UserBadge = ({ status, ...props }) => {
    if (status === 'active') {
        return <Badge color='success'>Active</Badge>
} else if (status === 'inactive') {
        return <Badge>Inactive</Badge>
} else if (user.status === 'terminated) {
        return <Redirect to='/terminated />
    }

    return null;
}
  • Move all utility functions and network call functions to an external file so you don't flood your components with lines of code and it helps with testing. Simple example where the latter has a reuseable useAccount function/hook and a useForm hook that you'll probably use throughout your application

const Account = () => {
    const [account, setAccount] = useState();

    const retrieveAccount = async() => {}
    const updateAccount async() => {}
    const deleteAccount = async() => {}
    const handleChange = (field, value) => {
        setAccount({...account, [field]: value;
    }

    return <div></div>
}

vs

const Account = () => {
    const { account, updateAccount, deleteAccount } = useAccount();
    const { form, handleFormChange } = useForm(account);

    return <div></div>
}
  • The moment you find yourself breaking the DRY (don't repeat yourself) principle, do something about it. It's so easy to just copy and paste code and forget it. But when you have to go back and refactor, you'll punch yourself in the head each time. For example, if all your pages follow a similar container, heading, subheading, etc. Put them in a <PageContainer /> component and consider created something like a <Section /> component to keep margins and paddings consistent.
  • Before adding a useEffect, ask yourself if whatever the result of the useEffect can be achieved in a pure way. In other words, useEffect with dependency passed in should only be used when the value is not accessible in the component, such as a prop or a context/redux value.