不过,我面临的问题是,我想在整个组件树状结构中模仿 React 中 FlaskLogin current_user 的行为。对于不熟悉 FlaskLogin 的任何人,current_user只需存储当前登录用户的会话。
为此,我决定使用 React 上下文 api。我所做的是在顶级组件中,我将一个 UserProvider 包裹在应用程序周围,如下所示:
<UserProvider value={this.state.user}>
// Main Component.
</UserProvider>
Run Code Online (Sandbox Code Playgroud)
状态在构造函数中定义:
constructor() {
super();
this.state = {
user: {
id: -1,
username: ‘test username’,
email: 'test email’,
},
};
}
Run Code Online (Sandbox Code Playgroud)
然后我在 componentDidMount 中调用一个 Ajax 请求来获取 current_user。
componentDidMount() {
const state = this;
post('/get_current_user').then(function success(data) {
state.setState({
user: {
id: data.data.id,
username: data.data.username,
email: data.data.email,
},
});
}).catch(function exception() {
throw new Error('Failed to grab current user.');
});
} …Run Code Online (Sandbox Code Playgroud) 我有一个没有 redux 的应用程序,我使用钩子和钩子 useReducer + 上下文处理全局状态。我有 1 个 useReducer,它就像一个 Redux 商店。但要做到这一点,我只能发送 1 个减速器。在那个减速器中,我拥有状态的所有逻辑,但我想在其他减速器中分离该减速器的一些功能。在 redux 中有 combineReducer 来做到这一点。但是使用钩子+上下文,我该怎么做?如何在 useReducer 中组合多个 reducer 将其发送到我的 Global Provider?
//Global Provider
const [state, dispatch] = useReducer(reducer, {
isAuthenticated: null,
user: {},
catSelect: 10,
productsCart,
total
});
//reducer with all cases
export default function(state , action ){
switch(action.type) {
case SET_CURRENT_USER:
return etc...
case SET_CATEGORIA:
return etc...
case 'addCart':
return etc...
case etc....
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
现在这有效。但是 reducer 包含的“案例”与其他“案例”做的事情完全不同。例如一个“案例”用于认证,另一个“案例”添加产品,另一个“案例”消除供应商等。
使用 Redux,我会创建更多的 reducer(auth、shopCart、供应商等)并使用 combineReducer 来控制所有这些。
如果没有 …
有人可以向我解释为什么下一个代码会重新呈现来自提供者的所有子组件
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
const App = () => {
const [theme, setTheme] = useState(false);
console.log("App running");
return (
<ThemeContext.Provider value={{ theme, setTheme }} children={<Child1 />} />
);
};
const Child1 = () => {
console.log("Child1 running");
return (
<div className="child1">
<Child2 />
</div>
);
};
const Child2 = () => {
console.log("Child2 running");
return (
<div className="child2">
<Child3 />
</div>
);
};
const Child3 = () => {
const { …Run Code Online (Sandbox Code Playgroud) 我们如何在 React.CreateContext 中使用泛型?
我有这个:
interface Props {
}
export interface SearchContextProps {
dtos: any[];
}
export const SearchContext = React.createContext<SearchContextProps>({
dtos: []
});
const SearchPage: React.FunctionComponent<Props> = (props) => {
const [dtos, setDtos] = React.useState<any[]>([]);
const searchContext = {
dtos: dtos
};
return (
<SearchContext.Provider value={searchContext}>
...
</SearchContext.Provider>
);
}
export default SearchPage;
Run Code Online (Sandbox Code Playgroud)
现在我想使用泛型,所以我会写这样的内容:
interface Props<T> {
}
export interface SearchContextProps<T> {
dtos: T[];
}
export const SearchContext = React.createContext<SearchContextProps<T>>({
dtos: []
});
const SearchPage = <T extends object>(props: Props<T>) …Run Code Online (Sandbox Code Playgroud) 我有一个反应网络应用程序,在导航上有一个主题切换。我有一个ThemeProvider Context具有自动检测用户的系统主题首选项并设置它的逻辑。然而,我认为用户应该能够在网站上来回切换主题,无论他们的系统偏好如何。这是ThemeContext.js包含所有主题逻辑(包括方法)的文件toggle。
import React, { useState, useLayoutEffect } from 'react';
const ThemeContext = React.createContext({
dark: false,
toggle: () => {},
});
export default ThemeContext;
export function ThemeProvider({ children }) {
// keeps state of the current theme
const [dark, setDark] = useState(false);
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)')
.matches;
const prefersLight = window.matchMedia('(prefers-color-scheme: light)')
.matches;
const prefersNotSet = window.matchMedia(
'(prefers-color-scheme: no-preference)'
).matches;
// paints the app before it renders elements
useLayoutEffect(() => {
// Media …Run Code Online (Sandbox Code Playgroud) 我想拨打电话来获取用户信息并在整个应用程序的不同组件中使用它,所以我使用了react.Context,并且我设法在组件之间移动字符串,但是当我尝试使用 axios.get 时,我是无法将数据获取到另一个组件,这里是上下文代码:
import React, { createContext } from 'react';
import axios from 'axios';
export const userContext = createContext();
export const UserProvider = (props) => {
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': `JWT ${localStorage.getItem('access')}`,
'Accept': 'application/json'
}
};
const res = axios.get(`${process.env.REACT_APP_API_URL}/auth/users/me/`, config)
return(
<userContext.Provider value= { res }>{props.children}</userContext.Provider>
);
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我我在这里做错了什么吗
我正在将应用程序从 Firebase 迁移到 AWS Amplify。我想创建一个 React 上下文,如果用户未登录,它将提供路由保护。
例如,我的 Auth.js 文件:
import React, { useEffect, useState, createContext } from 'react'
import fire from './firebase'
export const AuthContext = createContext()
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null)
useEffect(() => {
fire.auth().onAuthStateChanged(setCurrentUser)
}, [])
return (
<AuthContext.Provider value={{ currentUser }}>
{children}
</AuthContext.Provider>
)
}
Run Code Online (Sandbox Code Playgroud)
我的 App.js 文件:
import * as React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import Navbar from './components/navbar/navbar'
import …Run Code Online (Sandbox Code Playgroud) 我想在react-query的钩子周围创建一个包装器钩子,useQuery以便我可以捕获401错误,尝试刷新访问令牌,如果成功刷新,则使原始查询无效。
我想要做的完整示例在这里: https: //codesandbox.io/s/agitated-booth-hbe12 ?file=/src/App.js
function useMyQUery() {
const queryClient = useQueryClient();
const { tryRefreshToken } = useSession();
const query = useQuery(...arguments);
if (query.isError && query.error?.status === 401) {
tryRefreshToken().then((tokenRefreshSucccessful) =>
queryClient.invalidateQueries("todos")
);
} else {
return query;
}
return {};
}
Run Code Online (Sandbox Code Playgroud)
在我上面链接的示例中,我能够捕获错误,触发函数tryRefetchToken,但挂钩内的函数useSession似乎在设置令牌后不会拾取令牌。
我想知道如何更改Storybook 中组件故事内的React Context的值。我想有一种方法可以通过故事控制来控制它,但没有任何文档。
我使用Storybook 文档的这一部分为我的故事提供两个单独的上下文。
我的代码.storybook/preview.js如下所示:
export const decorators = [
(Story) => (
<FilterProvider>
<SearchQueryProvider>
<Story />
</SearchQueryProvider>
</FilterProvider>
),
];
Run Code Online (Sandbox Code Playgroud)
和FilterProvider代码SearchQueryProvider如下所示:
const SearchQueryProvider = ({ children }: SearchQueryProviderProps) => {
const [searchQuery, setSearchQuery] = useState<string>("");
return (
<SearchQueryContext.Provider value={[searchQuery, setSearchQuery]}>
{children}
</SearchQueryContext.Provider>
);
};
export { SearchQueryProvider, useSearchQuery };
Run Code Online (Sandbox Code Playgroud)
这些状态的初始值基本上都是空的。为了测试和预览使用这些上下文的组件,我现在想更改 Storybook 中的值。
如果有人知道我如何实现这一目标:我很高兴知道并感谢您分享您的知识:)
所以我试图通过反应上下文实现一个简单的主题切换,并且我需要根据另一个组件(ThemeSwitcher.jsx)中的 onChange 事件更改上下文(在 ThemeProvider.jsx 中)提供程序的值。
主题提供者.jsx:
import React, {createContext} from "react";
import {THEME_TYPE} from "../constants";
export const ThemeContext = createContext(THEME_TYPE.LIGHT);
const ThemeProvider = ({ children }) => {
return <>
<ThemeContext.Provider value={//THEME_TYPE.LIGHT or THEME_TYPE.DARK)}>
{children}
</ThemeContext.Provider>
</>
};
export default ThemeProvider;
Run Code Online (Sandbox Code Playgroud)
主题切换器.jsx:
import React, {useContext} from "react";
import { THEME_TYPE } from "../constants";
import {ThemeContext} from "../providers/ThemeProvider";
const ThemeSwitcher = () => {
const themeMode = useContext(ThemeContext);
const handleThemeChange = (e) => {
//value of context should change according to …Run Code Online (Sandbox Code Playgroud) react-context ×10
reactjs ×10
javascript ×4
react-hooks ×2
aws-amplify ×1
axios ×1
css ×1
formik ×1
generics ×1
react-query ×1
reducers ×1
store ×1
storybook ×1
typescript ×1