在这个项目中,我使用React.createContext()方法来管理状态。我可以通过导入Context.Consumer并在类组件(或功能组件)的返回方法中使用此使用者来访问状态数据。请参阅下面的示例:
function App(){
return(
<Consumer>
{value=>{
const {basket} = value;
return <p> { basket.length() } </p>
}
}
</Consumer>
)
}Run Code Online (Sandbox Code Playgroud)
问题是我想从useEffect 挂钩分派一个操作,而不是从组件返回
这就是我想做的:
function App() {
useEffect(() => {
auth.onAuthStateChanged(authUser => {
if(authUser){
dispatch({ //I need to use dispatch methode here!!
type : 'SET_USER',
payload : authUser
})
}
else{
dispatch({ //I need to use dispatch methode here!!
type : 'SET_USER',
payload : null
})
}
})
}, []) …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似乎在设置令牌后不会拾取令牌。
概括:
1) 您知道如何在通过路由挂载/卸载 Context Provider 时保持其状态吗?2)或者你知道一个维护良好的 Flux 实现,它支持多个独立的商店?
详细:
除了 React 组件自己的状态,到目前为止我主要使用的是 redux。除了不喜欢全局管理每个状态的想法之外,即使它可能只与子树相关,它也会成为我的新项目的一个问题。
我们希望动态加载组件并通过路由添加到应用程序。为了让组件准备好即插即用,我们希望它们处理自己的状态(存储它,从服务器请求它,提供修改它的策略)。
我阅读了如何使用 redux 动态地将 reducer 添加到全局存储中,但我实际上发现 Reacts Context API 的方法更好,我可以在 Provider 中封装一些状态,并且可以在我需要的任何地方使用它。
我唯一的问题是,Provider 和 Consumer 是 React 组件,所以如果它们是组件的一部分,通过路由挂载和卸载,那么可能已经创建或获取一次的状态就消失了。
在我看来,除了暂时将状态存储在本地存储或服务器上之外,没有办法解决这个问题。有的话请告诉我!!!
如果不应该有更好的解决方案:
我还考虑了一个更原始的 Flux 实现,它允许多个存储,可以用相关的组件子树封装。但是除了 Redux 之外,我还没有真正找到任何维护良好的 Flux 实现。Mobx 是个例外,但我真的更喜欢 Redux 的 reducer 解决方案,而不是 Mobx 的可观察解决方案。再说一次,如果您知道维护良好的多商店 Flux 实现,请告诉我!!!
我会对一些反馈感到非常高兴,并希望您能将我指向一个比动态减速器 Redux 或临时持久化上下文状态更令人满意的方向。
非常感谢!
我有一个使用Redux的应用程序。是存储全局状态,如下所示:
创建商店:
import {createStore, applyMiddleware} from 'redux';
import rootReducer from '../reducers';
import thunk from 'redux-thunk';
const configureStore = initialState => {
return createStore(
rootReducer,
initialState,
applyMiddleware(thunk)
);
};
export default configureStore;
Run Code Online (Sandbox Code Playgroud)
处理本地存储
const storageName = 'xxxState';
export const loadState = () => {
try {
const serializedState = localStorage.getItem(storageName);
if (serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch(err) {
return undefined;
}
};
export const saveState = state => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem(storageName, …Run Code Online (Sandbox Code Playgroud) 我正在使用返回包装组件的 HOC 尝试新的上下文 API。当我使用这种Class.contextType = Context方法时它不起作用:
return function myHOC(WrappedComponent) {
class HOC extends React.Component {
// static contextType = MyContext;
render() {
console.log(this.context); // HERE, this logs `{}`
// ..do stuff
return <WrappedComponent {...this.props} />
}
}
HOC.contextType = MyContext;
return HOC;
};
Run Code Online (Sandbox Code Playgroud)
但是,我制作了相同的代码,但使用<MyContext.Consumer>它并且运行良好:
return function myHOC(WrappedComponent) {
const HOC = (props) => (
<MyContext.Consumer>
{(context) => {
console.log(context); // HERE, correct values
return <WrappedComponent {...props} />
}}
</MyContext.Consumer>
);
return HOC;
};
Run Code Online (Sandbox Code Playgroud)
我在这里没有看到什么吗?
我initializeIcons()仅在第一次访问站点时才需要运行一些功能(例如Office UI Fabric React的)和AXIOS调用(例如使用Context API检索登录的用户),然后将检索到的值存储在React Context中并进行它适用于整个应用程序。
Gatsby将我页面的内容包装在Layout中,例如:
const IndexPage = () =>
<Layout>
Body of Index Page...
</Layout>
Run Code Online (Sandbox Code Playgroud)
const AnotherPage = () =>
<Layout>
Body of Another Page...
</Layout>
Run Code Online (Sandbox Code Playgroud)
与布局是这样的:
const Layout = ({ children }) =>
<>
<Header />
<main>{children}</main>
<Footer />
</>
Run Code Online (Sandbox Code Playgroud)
我知道我可以不把我的背景:
在页面周围(或者将在每次点击页面时执行,并且其他页面也不可用):
const IndexPage = () =>
<MyContextProvider>
<Layout>
Context Available here
</Layout>
</MyContextProvider>
Run Code Online (Sandbox Code Playgroud)
const AnotherPage = () =>
<Layout>
Context NOT available here
</Layout>
Run Code Online (Sandbox Code Playgroud)在版式中(或每次都会执行): …
我在 ES6 上使用了最简单的上下文提供程序,但我无法将其转换为在 TypeScript 项目上使用。我搜索的每个网站在实现 context api 方面都有完全不同的看法。
它只是一个布尔变量和一个设置它的函数,我一直遇到 TypeScript 的问题。
我是否需要更改整个方法才能使其在 TypeScript 上运行?
上下文.js
import React from 'react'
import Reducer from './reducer'
export const LoadContext = React.createContext()
export const LoadProvider = ({ children }) => {
const [state, dispatch] = React.useReducer(Reducer, {
load: true
})
const setLoad = (load) => dispatch({ type: 'set_load', load })
return (
<LoadContext.Provider value={{ load: state.load, setLoad }}>
{children}
</LoadContext.Provider>
)
}
export const useLoadContext = () => React.useContext(LoadContext)
Run Code Online (Sandbox Code Playgroud)
减速器.js
export default (state, action) …Run Code Online (Sandbox Code Playgroud) 我有一个与此类似的上下文设置
const DataContext = createContext({ data: null });
const getData = (key) => {
switch(key) {
case 1:
return "Hello"
case 2:
return " World"
default:
return null
}
}
export const DataProvider = ({ id, children }) => {
const data = useMemo(() => {
return getData(id);
}, [id]);
return (
<DataContext.Provider
value={{
data,
}}
>
{children}
</DataContext.Provider>
);
};
export default DataContext
Run Code Online (Sandbox Code Playgroud)
以及像这样使用它的子组件
const HelloComponent = () => {
return <DataProvider id={1}>
{
// children are components that …Run Code Online (Sandbox Code Playgroud) 嘿,我正在寻求帮助。我在使用上下文 api 将数据从一个子组件传递到另一个子组件时遇到一些问题。但我得到了这个 typeError ,到目前为止我尝试了一些搜索,但运气不佳。如果有人不能指出我正确的方向,我将不胜感激!
谢谢
import { React, Component} from 'react';
export const MContext = React.createContext('');
class CurrencyProvider extends Component {
constructor() {
super()
this.state = {
setinputValue: (value) => this.setState({ inputValue: value })
}
}
render() {
return (
<MContext.Provider value={this.state}>
{this.props.children}
</MContext.Provider>)
}
}
export default CurrencyProvider;
Run Code Online (Sandbox Code Playgroud)
Dropdown.js
import { useQuery, gql } from "@apollo/client";
import { useState } from "react";
import './Dropdown.scss';
import { MContext } from "../CurrencyProvider";
const EXCHANGE_RATES = gql`
query GetExchangeRates { …Run Code Online (Sandbox Code Playgroud) react-context ×10
reactjs ×10
javascript ×3
aws-amplify ×1
axios ×1
consumer ×1
dispatch ×1
gatsby ×1
react-hooks ×1
react-query ×1
react-router ×1
reducers ×1
redux ×1
state ×1
typescript ×1