假设我实现了一个简单的全局加载状态,如下所示:
// hooks/useLoading.js
import React, { createContext, useContext, useReducer } from 'react';
const Context = createContext();
const { Provider } = Context;
const initialState = {
isLoading: false,
};
function reducer(state, action) {
switch (action.type) {
case 'SET_LOADING_ON': {
return {
...state,
isLoading: true,
};
}
case 'SET_LOADING_OFF': {
return {
...state,
isLoading: false,
};
}
}
}
export const actionCreators = {
setLoadingOn: () => ({
type: 'SET_LOADING_ON',
}),
setLoadingOff: () => ({
type: 'SET_LOADING_OFF',
}),
};
export const …Run Code Online (Sandbox Code Playgroud) 您好,我的初始状态为空对象,
let [value,setValue] = useState({});
function onSubmit(){
setValue({"new Object"})
}
Run Code Online (Sandbox Code Playgroud)
并在单击按钮时更新它。有什么方法可以在 useReducer 中实现这种情况,而且在这里我想创建一个新状态而不是改变它。非常感谢您的帮助或建议。
我有一个使用useState. 我现在想重构由应用程序管理的应用程序状态useReducer并继续使用localStorage.
我在弄清楚如何重构时遇到了麻烦,其中涉及到许多移动的部分。我如何重构内部的逻辑addToCartHandler以在ADD_TO_CART案例中使用?从那里,我相信我能够找出cartReducer. 谢谢你。
我的减速机:
export const initialUserState = {
username: '',
address: '',
token: '',
address: '',
loggedIn: false,
loaded: false,
};
export const userReducer = async (state, action) => {
try {
switch (action.type) {
case 'LOAD':
try {
const value = JSON.parse(await AsyncStorage.getItem('user_info'));
const newState = { ...state, ...value, loggedIn: true, loaded: true };
console.log('New State:', newState);
if (value !== null) {
return newState;
}
} catch (error) {
return { ...state, loaded: true };
}
break;
default:
return state;
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试在initialState 中使用axios 获取的一些数据,以便稍后可以将其与useReducer 一起使用。但是一旦我将它作为第二个参数的初始状态传递,它就会返回一个没有对象的空数组。请帮忙... :(
const [prods, setProds] = useState([]);
const getProds = () => {
axios.get(`API`).then((res) => {
const data = res.data;
setProds(data.products);
});
};
const result = prods.map(function (el) {
const quantity = Object.assign({}, el);
quantity.count = 0;
return quantity;
});
const initialState = {
products: [result],
};
useEffect(() => {
getProds();
}, []);
console.log(initialState);
const [countState, dispatch] = useReducer(counterReducer, initialState);
console.log(countState);
Run Code Online (Sandbox Code Playgroud)
第一个和第二个日志的结果如下所示:
将计数添加到每个 API 调用后的结果如下所示:
这是我的减速器的代码,我检查了很多次,但看起来不错:
export const counterReducer = (state, action) => {
switch …Run Code Online (Sandbox Code Playgroud) 我的印象是useState,useReducer除了当状态是复杂/嵌套对象时我们应该使用 useReducer 之外,两者的工作方式相似。
但是今天我发现了一个奇怪的行为,我正在遍历一个数组并将值设置为一个状态对象。我使用useState和做了同样的例子useReducer。
With useState:它只将数组中的最后一个值推送到状态对象,因为 useState 本质上是异步的,所以当我们在循环中设置状态时,它可能无法根据之前的状态正确更新。所以你只得到状态中的最后一个对象。
使用useReducer:我期待 useReducer 具有相同的行为,但是使用 useReducer,当我们dispatch从循环内部执行操作时,它似乎可以正确设置状态。所以在这里你得到状态内的所有对象。
使用状态
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
const [students, setStudents] = React.useState({});
const createStudents = () => {
const ids = [1,2,3];
const names = ['john', 'michael', 'greg']
for(let i = 0; i < 3; i++){
const student = {[ids[i]]: names[i]};
setStudents({...students, ...student})
}
}
return (
<div className="App">
<button …Run Code Online (Sandbox Code Playgroud)我在官方的 next.js 示例中发现了这一点,state并且dispatch将信息放在了单独的上下文提供程序中。
这样做的意义何在?这种做法是否可以防止不必要的重新渲染?
export const CounterProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, 0)
return (
<CounterDispatchContext.Provider value={dispatch}>
<CounterStateContext.Provider value={state}>
{children}
</CounterStateContext.Provider>
</CounterDispatchContext.Provider>
)
}
export const useCount = () => useContext(CounterStateContext)
export const useDispatchCount = () => useContext(CounterDispatchContext)
Run Code Online (Sandbox Code Playgroud) 我添加了一个上下文,其中包含useReducer我的 Ionic React 应用程序的钩子。我看到一些奇怪的行为:当我通过调用更新上下文值时dispatch,页面上的消费者组件将被更新,但选项卡栏上完全相同的组件不会更新。
我按照这个教程进行了操作。
当我添加console.log语句来检查组件是否正在重新加载时,我发现<TabBarCounter>即使上下文值已更改,放置在选项卡栏 ( ) 中的组件也没有重新加载。
当我添加语句来检查上下文提供程序中的重新渲染时,我发现调用console.loga 时它也不会重新渲染。dispatch
上下文似乎是在本地更新,而不是全局更新。这个答案中有一条评论:
您正在使用减速器正确更新状态,但它只会更新本地组件状态,而不是全局上下文状态。
这听起来很像我在这里遇到的问题。
这是一些代码:
MyContext.tsx
export const CountContext = React.createContext<any>({} as {
countState: CountState,
countDispatch: React.Dispatch<CountReducerActions>,
});
interface MyProps {
children: JSX.Element,
}
const reducer = (countState: CountState, action: CountReducerActions) => {
switch (action.type) {
case 'add1': {
countObject.total += 1;
return countObject;
}
default: {
throw new Error();
}
}
};
export const …Run Code Online (Sandbox Code Playgroud) 我有一个表单,我想function usePostAddList()在AddList(). function onSubmit()基本上就是usePostAddList()提出请求POST。
这是代码AddList():
添加列表.jsx
export default function AddList() {
..
..
const onSubmit = (e) => {
e.preventDefault()
const data = [
{
komoditas,
areaKota,
areaProvinsi,
price,
tglParsed,
},
]
// I called it here and it show an error
usePostAddList(data)
}
..
..
}
Run Code Online (Sandbox Code Playgroud)
减速器/index.js
export function usePostAddList(data) {
const [state, dispatch] = React.useReducer(reducer, initState)
React.useEffect(() => {
dispatch({ type: ACTIONS.MAKE_REQUEST })
store
.append("Sheet2", data)
.then((res) …Run Code Online (Sandbox Code Playgroud) 我有一个父组件,它根据 useReducer 中名为 state.viewOption 的状态选择要渲染的视图。
调度它的子组件类似于:
export default function SearchFilter({ placeholder, onSearch }) {
const [state, dispatch] = useReducer(
collectionListReducer,
initialCollectionState
);
const option = state.viewOption;
const handleChange = e => dispatch(setSketchesTrendsOption(e.target.value));
return (
<Grid container>
<Grid item className={classes.selector}>
<TextField
select
id="sketches-trends-selector"
value={option}
onChange={handleChange}
>
<MenuItem value="Sketches">{t('TR_SKETCHES')}</MenuItem>
<MenuItem value="Trends">{t('TR_TRENDS')}</MenuItem>
</TextField>
</Grid>
);
}
Run Code Online (Sandbox Code Playgroud)
然后我想根据这个状态选择视图选项的父组件是这样的:
export default function CollectionListOption() {
const [state, dispatch] = useReducer(
collectionListReducer,
initialCollectionState
);
const viewOption = state.viewOption;
useEffect(() => {
console.log('view option in useEffect', viewOption);
}, …Run Code Online (Sandbox Code Playgroud) reactjs ×10
use-reducer ×10
react-hooks ×6
javascript ×5
context-api ×1
ionic-react ×1
next.js ×1
redux ×1