我有一个使用的自定义挂钩useReducer。
function useMyCustomHook() {
const [state, dispatch] = useReducer(EntityReducer, initialState);
// console.log(state); // 1- state is up to date here
const customDispatch = (action) => {
dispatch({ ...action }); // first call EntityReducer by action.type
//2- I use state and dispatch here(for example:use state for call an api, then dispatch response)
// but the state is previous not new state?
switch (action.type) {
case "something":
// use dispatch and state here
return state;
}
}
return [state, customDispatch]; …Run Code Online (Sandbox Code Playgroud) 我的目标是使用 hook 实现 React 控制的输入useReducer。
在减速器内部,我需要event.target.value和event.target.selectionStart来获取当前值和插入符位置。所以我考虑过发送event作为payload操作的ON_CHANGE。
这就是我正在尝试的:
https://codesandbox.io/s/optimistic-edison-xypvn
function reducer(state = "", action) {
console.log("From reducer... action.type: " + action.type);
switch (action.type) {
case "ON_CHANGE": {
const event = action.payload;
const caretPosition = event.target.selectionStart;
const newValue = event.target.value;
console.log("From reducer... event.target.value: " + event.target.value);
console.log(
"From reducer... event.target.selectionStart: " + caretPosition
);
return newValue;
}
default: {
return state;
}
}
}
export default function App() {
console.log("Rendering …Run Code Online (Sandbox Code Playgroud) 我正在建立该国餐馆的目录。该 API 返回一组对象,每个对象都包含诸如restaurantName、restaurantLocation、restaurantPriceRange 等字段。
我想创建一个过滤组件,它将餐厅数组减少到仅包含那些符合搜索条件的餐厅的子集。我还需要通过 URL 传递过滤器值,为此我认为应该使用路由器。
我正在考虑使用 useState 挂钩存储初始数据集,然后使用 useReducer 存储活动过滤器选择和过滤后的餐厅集合的子集,仅包含那些与搜索条件匹配的餐厅集合,但我觉得这是一个笨拙的解决方案,因为我有效将复制整个餐厅集合的一个子集。
但是,如果我不使用 useState 将初始数据集存储在单独的对象中,则一旦应用过滤器,所有不匹配的内容都将永远消失。
实现这一目标的最佳方法是什么?
免责声明:我知道如何在 JavaScript 中过滤数组,并且完全了解过滤器、映射、排序等功能。这个问题是关于 React 生态系统的,以及在反应应用程序。我知道当我为其编写代码时,我仍然需要在我的减速器中使用 Array.prototype.filter 。
我如何等待调度更新状态?我在 useReducer API 文档中没有找到任何内容,在 TypeScript 类型定义中也没有找到任何指示。
这是我尝试过但没有成功的方法:
await new Promise<void>((resolve) => {
dispatch({ type: DO_SOMETHING, something });
resolve();
});
console.log(state.something); // still the old version
Run Code Online (Sandbox Code Playgroud) 这是一个类组件,我想使用它重构为功能组件useReducer
export default class FootballMatchesData extends Component {
constructor(props) {
super(props);
this.state = {
selectedYear: null,
matchData: [],
firstCall: false
};
}
chooseYear = (year) => (e) => {
this.setState({
selectedYear: year
})
axios.get(`https://website?property=${year}`)
.then(res => {
this.setState({ matchData: res.data, firstCall: true })
})
}
render() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在定义我的减速器的“CHOOSE_YEAR”情况。我将如何定义这种情况,以便:
selectedYearhttps://website?property=${year},然后填充matchDatafirstCall这是我当前的重构。https://codesandbox.io/s/gracious-pare-um66h?file=/src/FootballMatches.js
我创建了一个沙箱来概述主要兴趣点: https://codesandbox.io/s/restless-dawn-nwy0l
请忽略格式,因为这只是我整理的 MWE。
当我在上面的沙箱中运行以下测试时
import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import Statistics from "../src/components/Block/Statistics";
import { IAction, IState } from "../src/typings/AppTypes";
import { AppReducer } from "../src/reducers/AppReducer";
import { AppContext } from "../src/context/AppContext";
import * as MineUtil from "../src/utils/mine";
import * as ConversionUtil from "../src/utils/conversion";
const state: IState = {
verifiedTrans: [
{
to: "A",
from: "B",
amount: 1.23,
message: "First Transaction",
signature: "AB1.23"
},
{
to: "A",
from: …Run Code Online (Sandbox Code Playgroud)reactjs jestjs react-testing-library use-reducer use-context
我目前正在尝试弄清楚如何在将应用程序包装在 Context 提供程序中(从 useReducer 获取值)然后通过带有 useEffect 挂钩的子组件进行更新时避免创建无限循环。
CodeSandbox 上有一个问题示例。
显然,如果不在这里重新发布所有代码,就很难谈论这个问题,但关键点是:
根:
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
const value = { state, dispatch };
return (
<Context.Provider value={value}>
...
</Context.Provider>
Run Code Online (Sandbox Code Playgroud)
孩子:
export const Page1: FC = () => {
const { dispatch, state } = useContext(Context);
const { isLoading } = state;
useEffect(() => {
dispatch({
type: "loading",
payload: false
});
}, [dispatch]);
return (...)
Run Code Online (Sandbox Code Playgroud)
我可能遗漏了一些明显的东西,但任何指针都可能会帮助遇到同样问题的其他人。
为什么这个警告框在一个简单的 useReducer 应用程序中出现两次,
单击此处 获取代码和框链接,
重新生成场景
这是代码
import "./styles.css";
import { useReducer } from "react";
const reducerFunction = (state, action) => {
switch (action.type) {
case "testing": {
if (action.payload.value > 0) {
return { ...state, testing: action.payload.value };
} else {
alert("some message");
return state;
}
}
default: {
throw new Error("Invalid Action");
}
}
};
export default function App() {
const defaultValue = {
testing: 0
};
const [state, dispatch] = useReducer(reducerFunction, defaultValue);
return (
<input …Run Code Online (Sandbox Code Playgroud) 这里我想创建一个AuthContext来将用户状态共享给其他组件。这里我使用 TypeScript 来设置变量类型。但是当我试图解决这个问题时,我遇到了很多错误。我对这个问题非常困惑。
这是我的AuthContext:
import { createContext, ReactNode, useReducer } from 'react'
import { AuthReducer } from './Reducer';
export interface IState {
isAuthenticated: boolean
user: string | null
token: string | null
}
// interface for action reducer
export interface IAction {
type: 'LOGIN' | 'LOGOUT' | 'REGISTER' | 'FORGOT PASSWORD'
payload?: any
}
interface IAuthProvider {
children: ReactNode
}
const initialState = {
isAuthenticated: false,
user: '',
token: ''
}
export const AuthContext = createContext<IState>(initialState); …Run Code Online (Sandbox Code Playgroud) 这是我在函数组件中初始化的 useReducer 钩子。在listReducer函数中,我想创建用户==>我分配给状态用户类型的数组。所以,在有效负载中我必须有User[]. 但是,当我通过 _id 删除 ==> 仅其中单个元素时(必须使用私有变量来解决),我必须将字符串类型传递给有效负载。
type State = {
list: User[];
}
const initialListState: State = {
list: [],
};
enum ActionKind {
CREATE = 'CREATE',
DELETE = 'DELETE',
}
type Action = {
type: ActionKind,
payload: User[] | string;
}
function listReducer(state: State, action: Action): State {
const { type, payload } = action;
switch (type) {
case ActionKind.CREATE:
return { list: action.payload };
case ActionKind.DELETE:
return {
list: state.list.filter((el) => el._id …Run Code Online (Sandbox Code Playgroud) use-reducer ×10
reactjs ×9
react-hooks ×6
javascript ×3
use-context ×3
typescript ×2
alert ×1
filtering ×1
input ×1
jestjs ×1
state ×1
use-effect ×1
use-state ×1