# ビジネス ロジックの UI コンポーネントからの分離

Copilot Chat は、ビジネス ロジックをユーザー インターフェイス コードから分離し、アプリケーションの保守とスケーリングを容易にするのに役立ちます。

多くのフロントエンド フレームワークでは、ビジネス ロジックがユーザー インターフェイス (UI) コンポーネント内に埋め込まれることがあり、特にアプリケーションが大きくなるにつれて、コードの保守や拡張が困難になります。

Copilot Chat は、コードをリファクタリングして、ビジネス ロジックを個別のサービスまたは状態管理ソリューションに抽出するのに役立ちます。 これにより、ビジネス ロジックをさまざまな UI コンポーネントで再利用できるようになります。 また、懸念事項を分離し、相互依存関係を減らすことでコードの拡張が容易になります。また、ビジネス ロジックを UI コンポーネントから独立してテストできるようになるため、単体テストも簡略化されます。

## サンプル シナリオ

この JavaScript コードでは、`Counter` コンポーネントでコンポーネントのビジネス ロジックを構成し、Web ページ内でコンポーネントを使うための UI コードも定義しています。

```javascript id=counter-component
import React, { useState } from 'react';

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

  const increment = () => {
    if (count >= 10) {
      alert('Count cannot exceed 10');
      return;
    }
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
};

export default Counter;
```

## プロンプトの例

```copilot copy prompt ref=counter-component
Use Redux to separate the UI code from the Counter component in this code.
```

## 応答の例

Copilot には、コードをリファクタリングするための詳細な手順が用意されています。

提案される変更は、状態管理に Redux を使うように `Counter` コンポーネントをリファクタリングするものです。 これには、初期状態とレジューサーを使用した Redux ストアの設定、インクリメント アクションの定義、Redux ストアに接続するための `Counter` コンポーネントの変更が含まれます。 最後に、Redux ストアを `Provider` コンポーネントで使用できるように、アプリケーションは `Counter` コンポーネントでラップされます。 これにより、UI ロジックは状態管理から分離されます。

提案された変更により、コードは 5 つの個別のファイルに分割されます。

> \[!NOTE]
> Copilot Chat 応答は非決定論的であるため、ここで説明した応答とは異なる応答が得られる場合があります。

### actions.js

```javascript
export const increment = () => ({
  type: 'INCREMENT'
});
```

### reducer.js

```javascript
const initialState = {
  count: 0
};

const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      if (state.count >= 10) {
        alert('Count cannot exceed 10');
        return state;
      }
      return {
        ...state,
        count: state.count + 1
      };
    default:
      return state;
  }
};

export default counterReducer;
```

### store.js

```javascript
import { createStore } from 'redux';
import counterReducer from './reducer';

const store = createStore(counterReducer);

export default store;
```

### counter.js

```javascript
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment } from './actions';

const Counter = () => {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
    </div>
  );
};

export default Counter;
```

### index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './counter';

ReactDOM.render(
  <Provider store={store}>
    <Counter />
  </Provider>,
  document.getElementById('root')
);
```

## 詳細については、次を参照してください。

* [GitHub Copilot Chat のプロンプト エンジニアリング](/ja/copilot/concepts/prompting/prompt-engineering)
* [GitHub Copilot の使用に関するベスト プラクティス](/ja/copilot/get-started/best-practices)