react/redoxプロジェクトの作成
60204 ワード
Redux installation ans setup
プロジェクトを作成し、react-router-dom
、axios
、react react-router
のパッケージをインストールします.
React/Redux Project Structure
プロジェクト内にディレクトリを作成して、構造を調整します.
src内部にフォルダとファイルを作成します.
containers:構成部品を含むフォルダ
redux:redux関連フォルダとファイル.
-actions:宣言されたActionsファイルに入ります.
-constants:action-typeファイルが入ります.
reducers:reduce関連ファイルが入ります.
Create Reduce Actions Types constants
フォルダ内にaction-types.js
ファイルが作成され、アクションタイプが作成されます.export const ActionTypes = {
SET_PRODUCTS : "SET_PRODUCTS",
SELECTED_PRODUCT: "SELECTED_PRODUCT",
REMOVESELECTED_PRODUCT: "REMOVE_SELECTED_PRODUCT",
}
Create Redux Actions import { ActionTypes } from "../constants/action-types"
export const setProducts = (products) => {
return {
type:ActionTypes.SET_PRODUCTS,
payload: products,
}
};
export const selectedProduct = (product) => {
return {
type: ActionTypes.SELECTED_PRODUCT,
payload: product,
};
};
Create Reducers productReducer.js
import { ActionTypes } from "../constants/action-types";
const initialState = {
products: [{
id : 1,
title:"jyc",
category:"human",
},
],
}
export const productReducer = (state, {type, payload) => {
switch(type){
case ActionTypes.SET_PRODUCTS:
return state;
default:
break;
}
}
src/reducers/index.js
import { combineReducers } from "redux";
import { productReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
})
export default reducers
Create Redux Store store.js
import { createStore } from "redux";
import reducers from "./reducers/index";
const store = createStore(
reducers,
{},
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSTION__()
);
export default store;
Connect React with Redux index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Create React Components Header
:ヘッダーimport React from 'react';
const Header = () => {
return (
<div className="ui fixed menu">
<div className='ui container center'>
<h2>WhateverShop</h2>
</div>
</div>
)
}
export default Header
ProductComponents
:製品import React from 'react';
const ProductComponent = () => {
return(
<div>
<h1>ProductComponent</h1>
</div>
)
}
export default ProductComponent
ProductDetail
:製品リストをクリックしたときに表示される詳細import React from 'react';
const ProductDetail = () => {
return(
<div>
<h1>ProductDetail</h1>
</div>
)
}
export default ProductDetail
ProductListing
:製品リストimport React from 'react';
const ProductListing = () => {
return(
<div>
<h1>ProductListing</h1>
</div>
)
}
export default ProductListing
まず簡単に作成し、ルートを追加して、それから詳しく作成します.
Add Routing to Projects app.js
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
UseSelector to access state ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
プロジェクト内にディレクトリを作成して、構造を調整します.
src内部にフォルダとファイルを作成します.
containers:構成部品を含むフォルダ
redux:redux関連フォルダとファイル.
-actions:宣言されたActionsファイルに入ります.
-constants:action-typeファイルが入ります.
reducers:reduce関連ファイルが入ります.
Create Reduce Actions Types constants
フォルダ内にaction-types.js
ファイルが作成され、アクションタイプが作成されます.export const ActionTypes = {
SET_PRODUCTS : "SET_PRODUCTS",
SELECTED_PRODUCT: "SELECTED_PRODUCT",
REMOVESELECTED_PRODUCT: "REMOVE_SELECTED_PRODUCT",
}
Create Redux Actions import { ActionTypes } from "../constants/action-types"
export const setProducts = (products) => {
return {
type:ActionTypes.SET_PRODUCTS,
payload: products,
}
};
export const selectedProduct = (product) => {
return {
type: ActionTypes.SELECTED_PRODUCT,
payload: product,
};
};
Create Reducers productReducer.js
import { ActionTypes } from "../constants/action-types";
const initialState = {
products: [{
id : 1,
title:"jyc",
category:"human",
},
],
}
export const productReducer = (state, {type, payload) => {
switch(type){
case ActionTypes.SET_PRODUCTS:
return state;
default:
break;
}
}
src/reducers/index.js
import { combineReducers } from "redux";
import { productReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
})
export default reducers
Create Redux Store store.js
import { createStore } from "redux";
import reducers from "./reducers/index";
const store = createStore(
reducers,
{},
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSTION__()
);
export default store;
Connect React with Redux index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Create React Components Header
:ヘッダーimport React from 'react';
const Header = () => {
return (
<div className="ui fixed menu">
<div className='ui container center'>
<h2>WhateverShop</h2>
</div>
</div>
)
}
export default Header
ProductComponents
:製品import React from 'react';
const ProductComponent = () => {
return(
<div>
<h1>ProductComponent</h1>
</div>
)
}
export default ProductComponent
ProductDetail
:製品リストをクリックしたときに表示される詳細import React from 'react';
const ProductDetail = () => {
return(
<div>
<h1>ProductDetail</h1>
</div>
)
}
export default ProductDetail
ProductListing
:製品リストimport React from 'react';
const ProductListing = () => {
return(
<div>
<h1>ProductListing</h1>
</div>
)
}
export default ProductListing
まず簡単に作成し、ルートを追加して、それから詳しく作成します.
Add Routing to Projects app.js
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
UseSelector to access state ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
export const ActionTypes = {
SET_PRODUCTS : "SET_PRODUCTS",
SELECTED_PRODUCT: "SELECTED_PRODUCT",
REMOVESELECTED_PRODUCT: "REMOVE_SELECTED_PRODUCT",
}
import { ActionTypes } from "../constants/action-types"
export const setProducts = (products) => {
return {
type:ActionTypes.SET_PRODUCTS,
payload: products,
}
};
export const selectedProduct = (product) => {
return {
type: ActionTypes.SELECTED_PRODUCT,
payload: product,
};
};
Create Reducers productReducer.js
import { ActionTypes } from "../constants/action-types";
const initialState = {
products: [{
id : 1,
title:"jyc",
category:"human",
},
],
}
export const productReducer = (state, {type, payload) => {
switch(type){
case ActionTypes.SET_PRODUCTS:
return state;
default:
break;
}
}
src/reducers/index.js
import { combineReducers } from "redux";
import { productReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
})
export default reducers
Create Redux Store store.js
import { createStore } from "redux";
import reducers from "./reducers/index";
const store = createStore(
reducers,
{},
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSTION__()
);
export default store;
Connect React with Redux index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Create React Components Header
:ヘッダーimport React from 'react';
const Header = () => {
return (
<div className="ui fixed menu">
<div className='ui container center'>
<h2>WhateverShop</h2>
</div>
</div>
)
}
export default Header
ProductComponents
:製品import React from 'react';
const ProductComponent = () => {
return(
<div>
<h1>ProductComponent</h1>
</div>
)
}
export default ProductComponent
ProductDetail
:製品リストをクリックしたときに表示される詳細import React from 'react';
const ProductDetail = () => {
return(
<div>
<h1>ProductDetail</h1>
</div>
)
}
export default ProductDetail
ProductListing
:製品リストimport React from 'react';
const ProductListing = () => {
return(
<div>
<h1>ProductListing</h1>
</div>
)
}
export default ProductListing
まず簡単に作成し、ルートを追加して、それから詳しく作成します.
Add Routing to Projects app.js
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
UseSelector to access state ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import { ActionTypes } from "../constants/action-types";
const initialState = {
products: [{
id : 1,
title:"jyc",
category:"human",
},
],
}
export const productReducer = (state, {type, payload) => {
switch(type){
case ActionTypes.SET_PRODUCTS:
return state;
default:
break;
}
}
import { combineReducers } from "redux";
import { productReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
})
export default reducers
store.js
import { createStore } from "redux";
import reducers from "./reducers/index";
const store = createStore(
reducers,
{},
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSTION__()
);
export default store;
Connect React with Redux index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Create React Components Header
:ヘッダーimport React from 'react';
const Header = () => {
return (
<div className="ui fixed menu">
<div className='ui container center'>
<h2>WhateverShop</h2>
</div>
</div>
)
}
export default Header
ProductComponents
:製品import React from 'react';
const ProductComponent = () => {
return(
<div>
<h1>ProductComponent</h1>
</div>
)
}
export default ProductComponent
ProductDetail
:製品リストをクリックしたときに表示される詳細import React from 'react';
const ProductDetail = () => {
return(
<div>
<h1>ProductDetail</h1>
</div>
)
}
export default ProductDetail
ProductListing
:製品リストimport React from 'react';
const ProductListing = () => {
return(
<div>
<h1>ProductListing</h1>
</div>
)
}
export default ProductListing
まず簡単に作成し、ルートを追加して、それから詳しく作成します.
Add Routing to Projects app.js
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
UseSelector to access state ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Header
:ヘッダーimport React from 'react';
const Header = () => {
return (
<div className="ui fixed menu">
<div className='ui container center'>
<h2>WhateverShop</h2>
</div>
</div>
)
}
export default Header
ProductComponents
:製品import React from 'react';
const ProductComponent = () => {
return(
<div>
<h1>ProductComponent</h1>
</div>
)
}
export default ProductComponent
ProductDetail
:製品リストをクリックしたときに表示される詳細import React from 'react';
const ProductDetail = () => {
return(
<div>
<h1>ProductDetail</h1>
</div>
)
}
export default ProductDetail
ProductListing
:製品リストimport React from 'react';
const ProductListing = () => {
return(
<div>
<h1>ProductListing</h1>
</div>
)
}
export default ProductListing
まず簡単に作成し、ルートを追加して、それから詳しく作成します.Add Routing to Projects app.js
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
UseSelector to access state ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import "./App.css";
import Header from "./containers/Header";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ProductListing from "./containers/ProductListing";
import ProductDetail from "./containers/ProductDetail";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/" exact component={ProductListing} />
<Route path="/product/:productId" exact component={ProductDetail} />
<Route>404 Not Found!</Route>
</Routes>
</Router>
</div>
);
}
export default App;
ProductComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const {id, title} = products[0];
return(
<div className="four column wide">
<h1 className='ui link cards'>
<div className='card'>
<div className='image'></div>
<div className='content'>
<div className='header'>{title}</div>
</div>
</div>
</h1>
</div>
)
}
export default ProductComponent
Use Axios for Redux Api Call
faskstor apiを使用してアイテムの情報を取得します.
対応するコードを使用してデータをインポートします.ProductListing.js
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
再実行後、コンソールウィンドウを表示して、コンソール上のすべてのデータのステータスを表示できます.
Render Products Listing Page import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状
必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import React ,{useEffect} from 'react';
import { useSelector } from 'react-redux';
import ProductComponent from './ProductComponent';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setProducts } from '../redux/actions/prodectActions';
const ProductListing = () => {
const products = useSelector((state) => state);
const dispatch = useDispatch();
const fetchProducts = async() => {
const response = await axios.get('https://fakestoreapi.com/products').catch((err) => {
console.log("ERR", err)
});
dispatch(setProducts(response.data));
};
useEffect(()=> {
fetchProducts();
},[]);
console.log("products:" ,products);
return(
<div className='ui grid container'>
<ProductComponent/>
</div>
)
}
export default ProductListing
import React from "react";
import { useSelector } from "react-redux";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="four wide column" key={id} >
<div className="ui link cards">
<div className="card">
<div className="image">
<img src={image} alt={title} />
</div>
<div className="content">
<div className="header">{title}</div>
<div className="meta price">$ {price}</div>
<div className="meta">{category}</div>
</div>
</div>
</div>
</div>
);
});
return (
<>
{renderList}
</>
)
};
export default ProductComponent;
クリックして詳細ページを作成します.
作成
selectedProductReducer
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
default:
return state;
}
}
組合せReducersに対応するReducerを追加します.import { combineReducers } from "redux";
import { productReducer, selectedProductReducer } from "./productReducer";
const reducers = combineReducers({
allProducts: productReducer,
product:selectedProductReducer,
});
export default reducers;
詳細ページに記入します.このとき、fetchProductDetail
関数が記述され、対応するproductId
データのみが読み込まれてレンダリングされる.import React, {useEffect} from 'react';
import {useParams} from 'react-router-dom'
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { selectedProduct } from '../redux/actions/productActions';
import { useSelector } from 'react-redux';
const ProductDetail = () => {
const product = useSelector((state) => state.product)
const {image, title, price, category, description} = product
const {productId} = useParams();
const dispatch = useDispatch();
console.log(product)
const fetchProductDetail = async () => {
const response = await axios.get(`https://fakestoreapi.com/products/${productId}`).catch(err => {
console.log("Err", err);
});
dispatch(selectedProduct(response.data))
}
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
},[productId]);
return (
<div className="ui grid container">
{Object.keys(product).length === 0 ? (
<div>...Loading</div>
) : (
<div className="ui placeholder segment">
<div className="ui two column stackable center aligned grid">
<div className="ui vertical divider">AND</div>
<div className="middle aligned row">
<div className="column lp">
<img className="ui fluid image" src={image} />
</div>
<div className="column rp">
<h1>{title}</h1>
<h2>
<a className="ui teal tag label">${price}</a>
</h2>
<h3 className="ui brown block header">{category}</h3>
<p>{description}</p>
<div className="ui vertical animated button" tabIndex="0">
<div className="hidden content">
<i className="shop icon"></i>
</div>
<div className="visible content">Add to Cart</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}
export default ProductDetail
現状必要なアイテムをクリックすると、詳細ページに移動し、そのアイテムの詳細ページが表示されますが、少しおかしいです.
最初のアイテムをクリックし、別のアイテムをクリックすると、以前にクリックしたアイテムの情報が保存後に更新されるのをしばらく見ることができます.
したがって、「詳細項目」をクリックすると、残りの項目の情報が消去されます.
Select and Remove Action Types
だから私はこれをしました.
ユーザーは、プロジェクトを選択してからプロジェクトを選択し、ロードで以前に選択したすべてのプロジェクトのデータを削除し、以前の情報を保持しない役割を果たします.selectedProductReducer
内部にREMOVE SELECTED PRODUCTをケースとして追加.productReducer.js
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
そして、動作生成関数removeSelectedProduct
が記述される.productActions.js
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
最後に、ProductDetail
のuseEffect
の内容を削除します.このコンテンツをレンダリングする前に、dispatch
を使用してremoveSelectedProduct
を実行します. useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
結果
今は選択しても、以前の情報は残さず、欲しいデータだけが表示されます.
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました
https://velog.io/@jhs000123/reactredux-프로젝트-만들기
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
export const selectedProductReducer = (state={},{type, payload}) => {
switch(type) {
case ActionTypes.SELECTED_PRODUCT:
return {...state, ...payload};
case ActionTypes.REMOVE_SELECTED_PRODUCT:
return {};
default:
return state;
}
}
export const removeSelectedProduct = () => {
return {
type: ActionTypes.REMOVE_SELECTED_PRODUCT,
};
};
useEffect(() => {
if(productId && productId !== "") fetchProductDetail();
return () => {
dispatch(removeSelectedProduct());
}
},[productId]);
Reference
この問題について(react/redoxプロジェクトの作成), 我々は、より多くの情報をここで見つけました https://velog.io/@jhs000123/reactredux-프로젝트-만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol