Os padrões de design no ReactJS fornecem soluções padronizadas e comprovadas para problemas comuns no desenvolvimento de aplicativos. Usar esses padrões não apenas torna seu código mais legível e fácil de manter, mas também aumenta sua escalabilidade e robustez. Vamos mergulhar em alguns dos padrões de design ReactJS mais populares, com exemplos para ilustrar seu uso.
O padrão Container e Presentational separa os componentes em duas categorias:
Essa separação permite melhor reutilização, testes mais fáceis e código mais limpo.
Exemplo: componentes de apresentação e contêiner
// Presentational Component: Displaying User List (UserList.js) import React from 'react'; const UserList = ({ users }) => (
// Container Component: Fetching User Data (UserContainer.js) import React, { useState, useEffect } from 'react'; import UserList from './UserList'; const UserContainer = () => { const [users, setUsers] = useState([]); useEffect(() => { const fetchUsers = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await response.json(); setUsers(data); }; fetchUsers(); }, []); return; }; export default UserContainer;
Aqui, UserList é um componente de apresentação que recebe usuários como acessórios, enquanto UserContainer lida com a busca de dados e o gerenciamento de estado.
Um Componente de ordem superior (HOC) é uma função que recebe um componente como argumento e retorna um novo componente. HOCs são comumente usados para questões transversais, como autenticação, registro ou melhoria do comportamento do componente.
Exemplo: Criando um HOC para autorização
// withAuthorization.js (HOC for Authorization) import React from 'react'; const withAuthorization = (WrappedComponent) => { return class extends React.Component { componentDidMount() { if (!localStorage.getItem('authToken')) { // Redirect to login if not authenticated window.location.href = '/login'; } } render() { return; } }; }; export default withAuthorization;
// Dashboard.js (Component Wrapped with HOC) import React from 'react'; import withAuthorization from './withAuthorization'; const Dashboard = () =>Welcome to the Dashboard
; export default withAuthorization(Dashboard);
Ao envolver o Dashboard com withAuthorization, você garante que apenas usuários autenticados possam acessá-lo.
O padrão Render Props envolve o compartilhamento de código entre componentes usando uma propriedade cujo valor é uma função. Este padrão é útil para renderização dinâmica com base em certas condições ou estados.
Exemplo: usando acessórios de renderização para rastreamento de mouse
// MouseTracker.js (Component with Render Props) import React, { useState } from 'react'; const MouseTracker = ({ render }) => { const [position, setPosition] = useState({ x: 0, y: 0 }); const handleMouseMove = (event) => { setPosition({ x: event.clientX, y: event.clientY }); }; return{render(position)}; }; export default MouseTracker;
// App.js (Using Render Props) import React from 'react'; import MouseTracker from './MouseTracker'; const App = () => (( Mouse position: ({x}, {y})
)} /> ); export default App;
O componente MouseTracker usa um suporte de renderização para passar dados de posição do mouse para qualquer componente, tornando-o altamente reutilizável.
Ganchos personalizados permitem encapsular e reutilizar lógica com estado em vários componentes. Esse padrão promove a reutilização do código e a separação clara de interesses.
Exemplo: Criando um gancho personalizado para busca de dados
// useFetch.js (Custom Hook) import { useState, useEffect } from 'react'; const useFetch = (url) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { const response = await fetch(url); const result = await response.json(); setData(result); setLoading(false); }; fetchData(); }, [url]); return { data, loading }; }; export default useFetch;
// App.js (Using the Custom Hook) import React from 'react'; import useFetch from './useFetch'; const App = () => { const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts'); if (loading) returnLoading...; return (
O gancho personalizado useFetch encapsula a lógica de busca de dados, que pode ser reutilizada em diferentes componentes.
O padrão Compound Components permite que os componentes trabalhem juntos para gerenciar estado e comportamento. Este padrão é útil para construir componentes de UI complexos, como guias, acordeões ou menus suspensos.
Exemplo: Construindo guias com componentes compostos
// Tabs.js (Parent Component) import React, { useState } from 'react'; const Tabs = ({ children }) => { const [activeIndex, setActiveIndex] = useState(0); return React.Children.map(children, (child, index) => React.cloneElement(child, { isActive: index === activeIndex, setActiveIndex, index }) ); }; const Tab = ({ children, isActive, setActiveIndex, index }) => ( ); const TabPanel = ({ children, isActive }) => (isActive ?{children}: null); Tabs.Tab = Tab; Tabs.TabPanel = TabPanel; export default Tabs;
// App.js (Using Compound Components) import React from 'react'; import Tabs from './Tabs'; const App = () => (); export default App; Tab 1 Tab 2 Content for Tab 1 Content for Tab 2
O componente Tabs gerencia o estado, enquanto os componentes Tab e TabPanel trabalham juntos para exibir o conteúdo das guias.
Os componentes controlados são totalmente gerenciados pelo estado React, enquanto os componentes não controlados dependem do DOM para seu estado. Ambos têm seus usos, mas os componentes controlados são geralmente preferidos pela consistência e facilidade de manutenção.
Exemplo: componentes controlados versus componentes não controlados
// Controlled Component (TextInputControlled.js) import React, { useState } from 'react'; const TextInputControlled = () => { const [value, setValue] = useState(''); return ( setValue(e.target.value)} /> ); }; export default TextInputControlled;
// Uncontrolled Component (TextInputUncontrolled.js) import React, { useRef } from 'react'; const TextInputUncontrolled = () => { const inputRef = useRef(); const handleClick = () => { console.log(inputRef.current.value); }; return ( > ); }; export default TextInputUncontrolled;
Em componentes controlados, o React controla totalmente o estado do formulário, enquanto em componentes não controlados, o estado é gerenciado pelo próprio DOM.
O Hooks Factory Pattern envolve a criação de ganchos que geram e gerenciam dinamicamente vários estados ou comportamentos, fornecendo uma maneira flexível de gerenciar lógica complexa.
Exemplo: gerenciamento de estado dinâmico com fábrica de ganchos
// useDynamicState.js (Hook Factory) import { useState } from 'react'; const useDynamicState = (initialStates) => { const states = {}; const setters = {}; initialStates.forEach(([key, initialValue]) => { const [state, setState] = useState(initialValue); states[key] = state; setters[key] = setState; }); return [states, setters]; }; export default useDynamicState;
// App.js (Using the Hooks Factory) import React from 'react'; import useDynamicState from './useDynamicState'; const App = () => { const [states, setters] = useDynamicState([ ['name', ''], ['age', 0], ]); return (setters .name(e.target.value)} /> setters.age(parseInt(e.target.value))} />); }; export default App;Name: {states.name}
Age: {states.age}
Esta fábrica de ganchos cria e gerencia dinamicamente vários estados, fornecendo flexibilidade e código mais limpo.
Ao aproveitar esses padrões de design, você pode criar aplicativos React que são mais robustos, escaláveis e de fácil manutenção. Esses padrões ajudam você a escrever código limpo e reutilizável que segue as práticas recomendadas, garantindo que seu aplicativo seja mais fácil de desenvolver e gerenciar ao longo do tempo.
Gostaria de se aprofundar em algum desses padrões ou explorar outros tópicos?
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3