{"meta":{"title":"将业务逻辑从 UI 组件中分离出来","intro":"Copilot Chat 可以帮助你将业务逻辑与用户界面代码分开，从而更轻松地维护和缩放应用程序。","product":"GitHub Copilot","breadcrumbs":[{"href":"/zh/copilot","title":"GitHub Copilot"},{"href":"/zh/copilot/tutorials","title":"教程"},{"href":"/zh/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot 指南"},{"href":"/zh/copilot/tutorials/copilot-cookbook/refactor-code","title":"重构代码"},{"href":"/zh/copilot/tutorials/copilot-cookbook/refactor-code/decouple-business-logic","title":"分离业务逻辑"}],"documentType":"article"},"body":"# 将业务逻辑从 UI 组件中分离出来\n\nCopilot Chat 可以帮助你将业务逻辑与用户界面代码分开，从而更轻松地维护和缩放应用程序。\n\n在许多前端框架中，业务逻辑可能会嵌入到用户界面 (UI) 组件内，这使得代码难以维护或扩展，尤其是在应用程序不断发展的过程中。\n\nCopilot Chat 可帮助你重构代码，将业务逻辑提取到单独的服务或状态管理解决方案中。 这使得业务逻辑能够在不同的 UI 组件中重复使用。 通过分离关注点并减少相互依赖关系，这也使得代码更易于缩放，而且通过允许业务逻辑独立于 UI 组件进行测试，还简化了单元测试。\n\n## 示例方案\n\n在这段 JavaScript 代码中，`Counter` 组件为该组件配置业务逻辑，并且还定义了在网页中使用该组件的 UI 代码。\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## 示例提示\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## 示例响应\n\nCopilot 提供重构代码的分步说明。\n\n建议的更改对 `Counter` 组件进行重构，以使用 Redux 进行状态管理。 这包括设置一个带有初始状态和一个归约器的 Redux 存储，定义一个递增操作，并修改 `Counter` 组件以连接到 Redux 存储。 最后，使用 `Provider` 组件包装应用程序，以便向 `Counter` 组件提供 Redux 存储区。 这会将 UI 逻辑与状态管理分开。\n\n建议的更改将代码分成五个单独的文件。\n\n> \\[!NOTE]\n> Copilot Chat 响应是不确定的，因此你可能会得到与此处所述的响应不同的响应。\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## 延伸阅读\n\n* [GitHub Copilot 对话助手的提示设计](/zh/copilot/concepts/prompting/prompt-engineering)\n* [使用 GitHub Copilot 的最佳做法](/zh/copilot/get-started/best-practices)"}