LoginSignup
0
0

More than 1 year has passed since last update.

React( ReduxToolkit )の構成でアプリを作成をしました【Bulletin board App】

Last updated at Posted at 2022-09-16

環境の準備

①ターミナルでreactアプリケーションを作成する。

npx create-react-app <プロジェクト名> --template redux
cd <プロジェクト名>
yarn start

② 必要なパッケージをインストールする。

npm install @reduxjs/toolkit react-redux

コンポーネント・ファイル構成

  src
   ├─ features
        └── Posts.js
   ├── App.css
   ├── App.js
   ├── DummyData.js
   └── index.js
src / features / Posts.js
import { createSlice } from '@reduxjs/toolkit';
import { PostsData } from '../DummyData';

export const postSlice = createSlice({
  name: 'posts',
  initialState: { value: PostsData },
  reducers: {
    addPost: (state, action) => {
      state.value.push(action.payload);
    },
    deletePost: (state, action) => {
      state.value = state.value.filter((post) => post.id !== action.payload.id);
    },
  },
});
export const { addPost, deletePost } = postSlice.actions;
export default postSlice.reducer;
src/App.css
.App {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5rem;
  height: 100vh;
}

.App h1 {
  font-size: 2.5rem;
}

hr {
  margin-top: 20px;
  margin-bottom: 0;
}

.displayPosts .post {
  margin-top: 30px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  padding: 20px 30px;
  border-radius: 10px;
  min-width: 500px;
  background-color: white;
}

.displayPosts .postName {
  font-size: 25px;
  margin-top: 6px;
}

.displayPosts .postContent {
  margin-top: -10px;
  font-size: 15px;
  font-weight: 400;
}

input {
  padding: 10px 20px;
  margin-right: 10px;
  border: none;
  box-shadow: 0 1px 3px 0 rgba(123, 123, 123, 0.1),
    0 6px 20px 0 rgba(118, 118, 118, 0.19);
  outline: none;
}

button {
  padding: 7px 30px;
  border: none;
  border-radius: 4px;
  box-shadow: 0 1px 3px 0 rgba(123, 123, 123, 0.1),
    0 6px 20px 0 rgba(55, 55, 55, 0.19);
  background-color: royalblue;
  color: white;
  cursor: pointer;
}

src/App.js
import './App.css';
import { useSelector, useDispatch } from 'react-redux';
import { addPost, deletePost } from './features/Posts';
import { useState } from 'react';

function App() {
  const [name, setName] = useState('');
  const [content, setContent] = useState('');

  //useSelectorでstoreの中のstateにアクセスできる。usersはreducer名
  const postList = useSelector((state) => state.posts.value);
  const dispatch = useDispatch();

  const handleClick = () => {
    dispatch(
      addPost({
        id: postList.length + 1,
        name: name,
        content: content,
      })
    );

    setName('');
    setContent('');
  };
  return (
    <div className='App'>
      <div>
        <h1>React-Redux掲示板</h1>
      </div>
      <div className='addPost'>
        <input
          type='text'
          placeholder='お名前'
          onChange={(e) => setName(e.target.value)}
          value={name}
        />
        <input
          type='text'
          placeholder='投稿内容'
          onChange={(e) => setContent(e.target.value)}
          value={content}
        />
        <button onClick={() => handleClick()}>投稿</button>
        <hr />
      </div>
      <div className='displayPosts'>
        {postList.map((post) => (
          <div key={post.id} className='post'>
            <h1 className='postName'>{post.name}</h1>
            <h1 className='postContent'>{post.content}</h1>
            <button onClick={() => dispatch(deletePost({ id: post.id }))}>
              削除
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;
src / DummyData.js
export const PostsData = [
  {
    id: 1,
    name: 'ShinCode',
    content: 'Redux勉強なう',
  },
  {
    id: 2,
    name: '名無しさん',
    content: 'ShinCodeさん分かりやすい',
  },
  {
    id: 3,
    name: '駆け出しエンジニア',
    content: 'Udemy受講してみようかな',
  },
  {
    id: 4,
    name: 'スタックオーバーフローさん',
    content: 'エンジニアのスタバ',
  },
];
src / index.css
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: lightyellow;
}
code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}
src / index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { configureStore } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import postsReducer from './features/Posts';

const store = configureStore({
  reducer: {
    posts: postsReducer,
  },
});

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

参考サイト

ReactとReduxを使って掲示板アプリを構築してみよう【Redux Toolkit実践】

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0