所以我想了解一下,React contexts但我有点困惑。从它的文档:
Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动向下传递 props。
所以这意味着我可以将应用程序的整个状态设为全局,并且可以从任何子组件更新它,对吧?但是我对如何使用它感到困惑。我有一个小应用程序,可以根据用户的输入向用户显示登录、注册或登录屏幕。我期望以下任何组件都应该能够更改存储在上下文中的全局对象的值,但我不确定如何使用它(提到不确定的函数todos)
// context
const MyAppSettings = React.createContext(
{
userId:null,
enableMarketing:false,
theme:"light"
}
)
Run Code Online (Sandbox Code Playgroud)
//ui components(having access to local state as well as global context
function SettingsUI({onThemeChange,onConsentChange}){
let settings = useContext(MyAppSettings)
return(
<div>
<button onClick={e=>onThemeChange()}>Change Theme to {settings.theme==="light"?"dark":"light"}</button>
<br/>
<button onClick={e=>onConsentChange()}> {settings.enableMarketing?"withdraw consent for marketing emails":"give consent for marketing emails"}</button>
</div>
)
}
function Auth({onAuthClick}){
let settings = useContext(MyAppSettings)
let textColor = settings.theme==="light" ? "black" : "white"
let bg = settings.theme==="light"?"white": "brown" …Run Code Online (Sandbox Code Playgroud) 我正在用 React 构建一个简单的游戏。问题是上下文已正确更新,但事件侦听器函数内的上下文值未更新。如果我访问事件函数外部的值,则会呈现新的更新值。
对于第一个 keyup 事件,该值将为 0,但对于下一个事件,它应该是新的更新值。
const updateGame = useUpdateGame();
const gameData = useGameData();
//Assume Default gameData.board value is 0
// Assume context value updated to 5
useEffect(() => {
document.addEventListener("keyup", (e) => {
e.stopImmediatePropagation();
console.log(gameData.board) //0
handleKeyPress(e.key, gameData.board, updateGame);
});
}, []);
console.log(gameData.board) //5
Run Code Online (Sandbox Code Playgroud) 我正在使用几个星期前发布的React Router的新useHistory挂钩。我的React-router版本是5.1.2。我的React版本为16.10.1。您可以在底部找到我的代码。
但是,当我从react-router导入新的useHistory时,出现此错误:
Uncaught TypeError: Cannot read property 'history' of undefined
这是由React-router中的这一行引起的
function useHistory() {
if (process.env.NODE_ENV !== "production") {
!(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useHistory()") : invariant(false) : void 0;
}
return useContext(context).history; <---------------- ERROR IS ON THIS LINE !!!!!!!!!!!!!!!!!
}
Run Code Online (Sandbox Code Playgroud)
由于它与useContext有关,并且可能与上下文冲突有问题,因此我尝试完全删除对useContext的所有调用,创建提供程序等。但是,此操作无济于事。试过React v16.8; 一样。我不知道是什么原因造成的,因为React路由器的所有其他功能都可以正常工作。
***请注意,调用其他React路由器挂钩(例如useLocation或useParams)时,也会发生相同的情况。
有人遇到过这种情况么?有什么想法可能导致这种情况吗?任何帮助将不胜感激,因为我在网上没有找到与此问题相关的信息。
import React, {useEffect, useContext} from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { …Run Code Online (Sandbox Code Playgroud) reactjs react-router react-router-dom react-context react-hooks
我使用 Context API 来管理我的应用程序全局状态,我第一次尝试使用钩子来做到这一点……我在 async/await 方面遇到了一些麻烦,让我解释一下:
这是我的提供者:
const JobProvider = (props) => {
const [modalOpen, setModalOpen] = useState(false)
const [modalJob, setModalJob] = useState({})
const [jobs, setJobs] = useState([])
const [searchItem, setSearchItem] = useState('')
const [page, setPage] = useState(1)
const [now, setNow] = useState('')
const handleSearchChange = (e) => {
setSearchItem(e.target.value)
}
const getJob = id => {
// bla bla bla
return something;
};
// ...
}
Run Code Online (Sandbox Code Playgroud)
在该 Provider 中,我有一个函数nextPage(),它只更新页码并在此之后返回它……这是具有该函数的 Provider:
const JobProvider = (props) => {
const …Run Code Online (Sandbox Code Playgroud) 根据文档:
当
<MyContext.Provider>组件上方最近的更新时,此 Hook 将使用传递给该 MyContext 提供程序的最新上下文值触发重新渲染。即使祖先使用React.memoorshouldComponentUpdate,仍然会使用 useContext 从组件本身开始重新渲染。...当上下文值更改时,调用 useContext 的组件将始终重新渲染。
在我的 Gatsby JS 项目中,我将我的 Context 定义为:
上下文.js
import React from "react"
const defaultContextValue = {
data: {
filterBy: 'year',
isOptionClicked: false,
filterValue: ''
},
set: () => {},
}
const Context = React.createContext(defaultContextValue)
class ContextProviderComponent extends React.Component {
constructor() {
super()
this.setData = this.setData.bind(this)
this.state = {
...defaultContextValue,
set: this.setData,
}
}
setData(newData) {
this.setState(state => ({
data: {
...state.data,
...newData,
}, …Run Code Online (Sandbox Code Playgroud) 我用 TypeScript 在 React.js 中创建了一个上下文,但发生了这个错误: 找不到命名空间 'JobContext'.ts(2503)
import React, { createContext, useState } from 'react';
export const JobContext = createContext<any>({});
const JobContextProvider = ({ children }) => {
const [data, setData] = useState<any>();
const updatingState = (newData) => setData({ ...data, ...newData });
return (
<JobContext.Provider value={{data, updatingState}}>
{children}
</JobContext.Provider>
);
};
export default JobContextProvider;
Run Code Online (Sandbox Code Playgroud) 我是 TS 的新手,我尝试将它与上下文 API 一起使用,但遇到了这个问题:当我尝试在提供程序中传递值时,我最终遇到了这个问题:
“类型 '{ Players: Player[]; }' 不可分配给类型 'Player[]'。
对象文字只能指定已知属性,并且类型 'Player[]' 中不存在 'players'。ts(2322) ”
这是我的代码:
interface Player {
players: [];
}
type WithChildren<T = {}> = T & { children: JSX.Element };
const PlayersProvider = ({ children }: WithChildren) => {
const [players, setPlayers] = useState<Player[]>([]);
useEffect(() => {
axios.get<{ players: Player[] }>(baseUrl + "/players").then((response) => {
setPlayers(response.data.players);
});
}, []);
return (
<PlayerContext.Provider value={{ players }}>
{children};
</PlayerContext.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
当我将它放在组件中时,它工作得很好,但由于我在上下文提供程序中外部化,所以它崩溃了。有人可以解释我出了什么问题吗?
我正在开发一个购物车系统,问题是,当我将产品添加到购物车时,它在上下文和本地存储中工作;但是,当我刷新时,数据就消失了。
export const DataContext = createContext();
export const DataProvider = ({ children }) => {
const [cart, setCart] = useState([]);
const [state, dispatch] = useReducer(AppReducer, cart);
useEffect(() => {
const cartData = JSON.parse(localStorage.getItem("cart"));
if (cartData) {
setCart(cartData);
}
}, []);
useEffect(() => {
localStorage.setItem("cart", JSON.stringify(cart));
// Cookies.set("cart", cart, { expires: 1 / 24 });
// let products = Cookies.get("cart");
// console.log(products);
}, [cart]);
const addToCart = (newProduct) => {
setCart((prev) => [...prev, newProduct]);
};
return (
<DataContext.Provider value={{ cart, setCart, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用自定义挂钩来调用将用于多个组件和上下文的函数。但是,钩子永远不会更新上下文值,它始终是一个空数组,但在上下文中,用作上下文值的状态会被更新,并且在组件中会接收上下文值。这里发生了什么?
在我看来,上下文值没有被传递给钩子,但我不明白为什么。
这是我的代码示例:
语境:
import { createContext, useState, useEffect } from "react";
import useTest from "./useTest";
const TestContext = createContext({
test: [],
testContextFn: () => {}
});
export const TestProvider = ({ children }) => {
const [testState, setTestState] = useState([]);
const { testFn } = useTest();
const testHandlerHandler = () => {
const test = 1;
setTestState((current) => [...current, test]);
testFn();
};
const contextValue = {
test: testState,
testContextFn: testHandlerHandler
};
useEffect(() => {
console.log("state: ", testState); // => …Run Code Online (Sandbox Code Playgroud) 我正在使用 React 和 Next.js 开发一个 Web 应用程序,并且我还有一个作为后端分离的 Node.js API。
我有一个登录表单,我将数据发送到 API 以恢复 JWT,当我这样做时,一切正常,但在将用户重定向到受保护的路由“仪表板”后,或者刷新后,用户上下文会丢失。
这是受保护的路线:
import React, {useContext, useEffect} from 'react'
import { useRouter } from "next/router";
import { Context } from '../../context/context';
export default function DashboardIndexView() {
const router = useRouter();
const {isUserAuthenticated, setUserToken, userToken} = useContext(Context);
useEffect(() => {
isUserAuthenticated()
? router.push("/dashboard")
: router.push("/authentication/admin");
}, []);
return (
<>
<h1>Dashboard index view</h1>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
这是上下文文件:
import React, {createContext, useEffect, useState} from 'react'
import { useRouter } from "next/router"; …Run Code Online (Sandbox Code Playgroud) 我正在关注 youtube 上的 React 教程,我正在尝试将项目从 JavaScript 转换为 TypeScript,但我在 useContext 方面遇到了很多麻烦,如果有人在这里帮助我,我将不胜感激。如果您想知道这里的教程是教程
import React, {createContext, useContext, useState } from 'react';
const StateContext = createContext();
export const ContextProvider = ({ children }) => {
const [activeMenu, setActiveMenu] = useState(true);
return (
<StateContext.Provider value={{activeMenu, setActiveMenu}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
Run Code Online (Sandbox Code Playgroud) react-context ×11
reactjs ×9
react-hooks ×6
javascript ×4
typescript ×3
next.js ×2
async-await ×1
gatsby ×1
jwt ×1
react-router ×1
use-context ×1