我通过reducer的初始状态获取类别状态项,但是获取redux状态的方式看起来有点混乱和硬编码,因此,我只想获取我自己创建的虚拟JSON数据,并使用json-server包提供,但是,我无法在useEffect钩子的render内部设置初始状态女巫调度redux-saga。有办法解决这个问题吗?
您可以理解代码块下面的操作的故事;
- 减速器块;如果没有我想用空对象更改的初始分派,下面的代码块 *
export const getCategoryReducer = (
state = {
category: [
{
id: '1',
name: 'bread',
url: 'https://via.placeholder.com/210/00FF00?text=1',
alt: 'bread',
},
{
id: '2',
name: 'croissant',
url: 'https://via.placeholder.com/220/00FF00?text=2',
alt: 'sdfalksdjflkasjdfk',
},
{
id: '3',
name: 'birthday-cake',
url: 'https://via.placeholder.com/230/00FF00?text=3',
alt: 'sdfalksdjflkasjdfk',
},
],
loading: false,
err: '',
},
action
) => {
switch (action.type) {
case LOAD_CATEGORY:
return {
...state,
loading: true,
};
case GET_CATEGORY_SUCCESS:
return {
...state,
category: action.category,
loading: false,
};
case GET_CATEGORY_FAIL:
return {
...state,
err: action.message,
loading: false,
};
default:
return state;
}
};
注意:initialState的项多于上述代码块
- 我尝试了通过Redux-saga使用UseEffect Hooks的调度操作,但是在页面渲染之前它不会加载json-server bakery类别的项目;*
useEffect(() => {
dispatch(getCategoryFetch('Bakery'));
}, []);
这是一个生成器函数,当操作通过时触发,然后从我创建的json-server本地服务器获取数据;
import { call, put, takeLatest } from 'redux-saga/effects';
const categoryFetch = async (category) => {
const res = await fetch(`http://localhost:3500/categories:`);
if (!res.ok) {
throw new Error('Something went wrong');
}
const data = await res.json();
return data[`${category}`];
};
function* getCategory(action) {
try {
const category = yield call(categoryFetch, action.payload);
yield put({ type: GET_CATEGORY_SUCCESS, category });
} catch (err) {
yield put({ type: GET_CATEGORY_FAIL, message: err.message });
}
}
export default function* mySagaCategory() {
yield takeLatest(LOAD_CATEGORY, getCategory);
}
在下面的代码中呈现动态类别项;
import React, { useCallback, useEffect, useMemo } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import {
LazyLoadImage,
LazyLoadComponent,
} from 'react-lazy-load-image-component';
import './ProductContainer.css';
const ProductConatiner = ({ category, err, loading, clickHandler }) => {
if (loading) {
document.querySelector('.progress-item').style.display = 'none';
return (
<SkeletonTheme className="container">
<Skeleton
color="grey"
highlightColor="#AAA"
className="handle skeleton"
// duration={2.5}
// height="55"
></Skeleton>
</SkeletonTheme>
);
}
if (err.length > 0) {
document.querySelector('.progress-item').style.display = 'none';
return (
<h1
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
color: 'red',
}}
>
{err + ' reload the page'}
</h1>
);
}
useEffect(() => {
document.querySelector('.progress-item').style.display = 'block';
}, []);
function quantityHandler() {
console.log('quantityHandler');
}
const Images = useMemo(() => {
return category.map((el, idx) => {
return (
<LazyLoadComponent>
<LazyLoadImage
delayTime={250}
delayMethod="throttle"
useIntersectionObserver={true}
threshold={500}
effect="opacity"
key={el.id}
src={el.url}
alt={el.name}
/>
<input
key={idx + 'input'}
className="image-input"
onChange={quantityHandler}
type="number"
value="1"
></input>
<label>kg</label>
</LazyLoadComponent>
);
});
}, [category]);
return (
<div className="container">
<button
onClick={(e) => clickHandler(e.target)}
className="handle left-handle"
>
<div className="text">‹</div>
</button>
<div className="slider">{Images}</div>
{/* <div className="inputs">{quantityItems} </div> */}
<button
onClick={(e) => clickHandler(e.target)}
className="handle right-handle"
>
<div className="text">›</div>
</button>
</div>
);
};
export default ProductConatiner;
1条答案
按热度按时间xa9qqrwz1#
在页面呈现之前不加载它是非常正常的,即使您找到了这样做的方法(通过延迟应用程序的启动),它也不能反映当今React开发的“现实”。
正常情况下,你的组件渲染时没有它需要的数据,然后执行useEffect,然后服务器在任何时间(可能是10 ms,也可能是10 s)应答。在这期间,你的组件负责检测数据是否不存在,并渲染一个“加载”状态。
因为这种模式几乎在你做的每件事上都是现实的,所以在这种情况下,你不会通过“作弊”来学到实质性的东西,而是从一开始就学习它。
话虽如此,你在这里使用的Redux的风格已经严重过时了。现代Redux(自2019年起)不再使用switch.. case reducers或ACTION_TYPES。此外,Redux-saga不再推荐用于大多数用例。由于现代Redux只占代码的1/4左右,因此您编写的不仅是过时的代码,您还编写了大量不必要的代码。请给予this article about modern Redux,然后考虑遵循the official Redux tutorial。
PS:你在
document.querySelector
上做的事情,使用外部元素的css样式作为“状态源”是有问题的--更新那些外部值永远不会使你的组件重新呈现。这意味着你的组件和那些外部值很容易失去同步。使用本地或全局(Redux)状态,而不是任意的元素属性。那些属性与你的应用程序生命周期不同步。