{"meta":{"title":"Decoupling business logic from UI components","intro":"Copilot Chat can help you separate your business logic from your user interface code, making it easier to maintain and scale your application.","product":"GitHub Copilot","breadcrumbs":[{"href":"/en/copilot","title":"GitHub Copilot"},{"href":"/en/copilot/tutorials","title":"Tutorials"},{"href":"/en/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot Cookbook"},{"href":"/en/copilot/tutorials/copilot-cookbook/refactor-code","title":"Refactor code"},{"href":"/en/copilot/tutorials/copilot-cookbook/refactor-code/decouple-business-logic","title":"Decouple business logic"}],"documentType":"article"},"body":"# Decoupling business logic from UI components\n\nCopilot Chat can help you separate your business logic from your user interface code, making it easier to maintain and scale your application.\n\nIn many front-end frameworks, business logic can become embedded within user interface (UI) components, making the code hard to maintain or extend, especially as the application grows.\n\nCopilot Chat can help you refactor your code to extract business logic into separate services or state management solutions. This allows the business logic to be reused across different UI components. It also makes the code easier to scale by separating concerns and reducing interdependencies, and it simplifies unit testing by allowing business logic to be tested independently from UI components.\n\n## Example scenario\n\nIn this JavaScript code, the `Counter` component configures the business logic for the component and also defines UI code for using the component in a web page.\n\n```javascript id=counter-component\nimport React, { useState } from 'react';\n\nconst Counter = () => {\n  const [count, setCount] = useState(0);\n\n  const increment = () => {\n    if (count >= 10) {\n      alert('Count cannot exceed 10');\n      return;\n    }\n    setCount(count + 1);\n  };\n\n  return (\n    <div>\n      <p>Count: {count}</p>\n      <button onClick={increment}>Increment</button>\n    </div>\n  );\n};\n\nexport default Counter;\n```\n\n## Example prompt\n\n```copilot copy prompt ref=counter-component\nUse Redux to separate the UI code from the Counter component in this code.\n```\n\n## Example response\n\nCopilot provides step-by-step instructions for refactoring the code.\n\nThe suggested changes refactor the `Counter` component to use Redux for state management. This includes setting up a Redux store with an initial state and a reducer, defining an increment action, and modifying the `Counter` component to connect to the Redux store. Finally, the application is wrapped with a `Provider` component to make the Redux store available to the `Counter` component. This separates the UI logic from state management.\n\nThe proposed changes separate the code into five separate files.\n\n> \\[!NOTE] Copilot Chat responses are non-deterministic, so you may get a different response from the one described here.\n\n### actions.js\n\n```javascript\nexport const increment = () => ({\n  type: 'INCREMENT'\n});\n```\n\n### reducer.js\n\n```javascript\nconst initialState = {\n  count: 0\n};\n\nconst counterReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case 'INCREMENT':\n      if (state.count >= 10) {\n        alert('Count cannot exceed 10');\n        return state;\n      }\n      return {\n        ...state,\n        count: state.count + 1\n      };\n    default:\n      return state;\n  }\n};\n\nexport default counterReducer;\n```\n\n### store.js\n\n```javascript\nimport { createStore } from 'redux';\nimport counterReducer from './reducer';\n\nconst store = createStore(counterReducer);\n\nexport default store;\n```\n\n### counter.js\n\n```javascript\nimport React from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { increment } from './actions';\n\nconst Counter = () => {\n  const count = useSelector(state => state.count);\n  const dispatch = useDispatch();\n\n  return (\n    <div>\n      <p>Count: {count}</p>\n      <button onClick={() => dispatch(increment())}>Increment</button>\n    </div>\n  );\n};\n\nexport default Counter;\n```\n\n### index.js\n\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport store from './store';\nimport Counter from './counter';\n\nReactDOM.render(\n  <Provider store={store}>\n    <Counter />\n  </Provider>,\n  document.getElementById('root')\n);\n```\n\n## Further reading\n\n* [Prompt engineering for GitHub Copilot Chat](/en/copilot/concepts/prompting/prompt-engineering)\n* [Best practices for using GitHub Copilot](/en/copilot/get-started/best-practices)"}