GatsbyJs + Redux Toolkit Saga + React Bootstrap + Storybook

GatsbyJs + Redux Toolkit Saga + React Bootstrap + Storybook I. Tạo và cài đặt các thư viện cần thiết 1. Init Gatsbyjsnpm init gatsby Bây giờ mình chạy thử cd name-project/ npm run develop Ứng dụng gatsby của bạn sẽ chạy trên cổng 8000 http://localhost:8000/ 2. Thêm storybook npx sb init npm install -D

GatsbyJs + Redux Toolkit Saga + React Bootstrap + Storybook

I. Tạo và cài đặt các thư viện cần thiết

1. Init Gatsbyjsnpm init gatsby

Bây giờ mình chạy thử

cd name-project/
npm run develop

Ứng dụng gatsby của bạn sẽ chạy trên cổng 8000
http://localhost:8000/

2. Thêm storybook

npx sb init
npm install -D dotenv-webpack
npm install -D html-webpack-plugin

npm run storybook

Ứng dụng của bạn sẽ chạy trên
http://localhost:6006/?path=/story/example-introduction--page

3. Thêm React Bootstrapnpm install [email protected][email protected]

4. Thêm Redux toolkit Saganpm install @reduxjs/toolkit react-redux redux-saga

II. Config store

  1. Bạn phải tạo file gatsby-browser.js vào trong dự án
import React from 'react';
import { Provider } from 'react-redux';
import store from './src/store/index';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

export const wrapRootElement = ({ element }) => {
  return <Provider store={store}>{element}</Provider>;
};

Tạo file gatsby-ssr.js

import React from 'react';
import { Provider } from 'react-redux';
import store from './src/store/index';

export const wrapRootElement = ({ element }) => {
  return <Provider store={store}>{element}</Provider>;
};

Tạo thêm file gatsby-node.js để có thể link đến thư mục của bạn khi SSR

const path = require('path');

exports.onCreateWebpackConfig = ({ actions }) => {
  actions.setWebpackConfig({
    resolve: {
      modules: [path.resolve(__dirname, 'src'), 'node_modules']
    }
  });
};

  1. Bạn cần tạo thư mục store

Cấu trúc sẽ tùy vào dự án của bạn. Trong ví dụ này mình sẽ cấu trúc store theo từng feature.
Nội dung các file trong store sẽ như sau
store/index.js

import { configureStore, Action, getDefaultMiddleware } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';

import rootReducers from './reducers';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();
const middleware = [...getDefaultMiddleware({ thunk: false }), sagaMiddleware];
const store = configureStore({
  reducer: rootReducers,
  middleware,
});

sagaMiddleware.run(rootSaga);
export default store

store/reducers.js

import { combineReducers } from "redux";
import count from "./features/count";

export default combineReducers({
  count,
});

store/features/count.js

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  count: 0,
};

// Slice
const countSlice = createSlice({
  name: "count",
  initialState,
  reducers: {
    setCount: (state, action) => {
      const { payload } = action;
      state.count = payload;
    },
  },
});

// Selectors
export const countSelector = (state) => state.count;

// Actions
export const { setCount } = countSlice.actions;

// Reducers
export default countSlice.reducer;

store/sagas/index.js

import { takeEvery } from 'redux-saga/effects';
import { sagaActions } from './typeSagas';
import { increaseCount } from './count';

export default function* rootSaga() {
  yield takeEvery(sagaActions.INCREASE, increaseCount);
}

store/sagas/count.js

import { put } from "redux-saga/effects";
import { setCount } from "../features/count";

export function* increaseCount(payload) {
  try {
    let result = payload.count + 1;
    yield put(setCount(result));
  } catch (e) {
    console.log(e);
  }
}

store/sagas/typeSagas.js

export const sagaActions = {
  INCREASE: 'INCREASE'
};

Done config cho store.
Các bạn kiểm tra với chrome devtool thì sẽ thấy store đã được khởi tạo.

Ok giờ thì sẽ sửa lại file pages/index.js nhé

import * as React from "react";
import { Badge, Button } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { countSelector } from "store/features/count";
import { sagaActions } from "../store/sagas/typeSagas";

const pageStyles = {
  color: "#232129",
  padding: 96,
  fontFamily: "-apple-system, Roboto, sans-serif, serif",
};
const headingStyles = {
  marginTop: 0,
  marginBottom: 64,
  maxWidth: "100%",
};
const headingAccentStyles = {
  color: "#663399",
};

const IndexPage = () => {
  const { count } = useSelector(countSelector);
  const dispatch = useDispatch();
  return (
    <main style={pageStyles}>
      <title>Home Page</title>
      <h1 style={headingStyles}>
        Congratulations
        <br />
        <span style={headingAccentStyles}>— you just made a Gatsby site! </span>
        <Badge bg="success">{count}</Badge>
        <span role="img" aria-label="Party popper emojis">
          🎉🎉🎉
        </span>
      </h1>
      <Button onClick={() => dispatch({ type: sagaActions.INCREASE, count })}>
        INCREASE
      </Button>
    </main>
  );
};

export default IndexPage;

Kết quả sẽ là thế này nhé

Bước cuối cùng chúng ta sẽ đi tích hợp store cho storybook nhé
Trong file storybook/preview.js các bạn cần tạo store cho storebook

import React from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from '../src/store/reducers'


export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
}

// config store for storybook
const storeInit = createStore(reducer)
export const decorators = [
  (Story) => (
    <Provider store={storeInit}>
      <Story />
    </Provider>
  ),
]

Có vẻ hơi dài nên sử dụng Storybook và cấu hình các bạn vào xem trong source nhé
Link source demo
https://github.com/vinctuyen/Gatsby-Redux-toolkit-Redux-saga-Storybook
Thanks for reading.

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,