- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据 docs :
When the nearest
<MyContext.Provider>
above the component updates, this Hook will trigger a rerender with the latest context value passed to that MyContext provider. Even if an ancestor usesReact.memo
orshouldComponentUpdate
, a rerender will still happen starting at the component itself using useContext. ... A component calling useContext will always re-render when the context value changes.
在我的 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,
},
}))
}
render() {
return <Context.Provider value={this.state}>{this.props.children}</Context.Provider>
}
}
export { Context as default, ContextProviderComponent }
在包含多个组件的layout.js 文件中,我放置了上下文提供程序:
Layout.js:
import React from 'react'
import { ContextProviderComponent } from '../../context'
const Layout = ({children}) => {
return(
<React.Fragment>
<ContextProviderComponent>
{children}
</ContextProviderComponent>
</React.Fragment>
)
}
在我希望使用上下文的组件中:
import React, { useContext } from 'react'
import Context from '../../../context'
const Visuals = () => {
const filterByYear = 'year'
const filterByTheme = 'theme'
const value = useContext(Context)
const { filterBy, isOptionClicked, filterValue } = value.data
const data = <<returns some data from backend>>
const works = filterBy === filterByYear ?
data.nodes.filter(node => node.year === filterValue)
:
data.nodes.filter(node => node.category === filterValue)
return (
<Layout noFooter="true">
<Context.Consumer>
{({ data, set }) => (
<div onClick={() => set( { filterBy: 'theme' })}>
{ data.filterBy === filterByYear ? <h1>Year</h1> : <h1>Theme</h1> }
</div>
)
</Context.Consumer>
</Layout>
)
Context.Consumer
工作正常,因为它成功更新并反射(reflect)了上下文的更改。然而,如代码中所示,我希望能够访问组件其他部分中更新的上下文值,即 return
之外的值。函数其中 Context.Consumer
被专门使用。我假设使用 useContext
hook 会对此有所帮助,因为每次单击 div 时,我的组件都会使用上下文中的新值重新渲染 - 但事实并非如此。任何帮助弄清楚为什么会出现这种情况的帮助将不胜感激。
TL;博士:<Context.Consumer>
更新并反射(reflect)子组件 useContext
对上下文的更改尽管组件需要它,但不会。
更新:我现在发现useContext
将从传递给 createContext
的默认上下文值中读取并且基本上将独立于 Context.Provider
运行。这就是这里发生的事情,Context.Provider
包括修改状态的方法,而默认上下文值则不会。我现在的挑战是找出一种方法,将一个函数包含在默认上下文值中,该函数可以修改该值的其他属性。就目前情况而言:
const defaultContextValue = {
data: {
filterBy: 'year',
isOptionClicked: false,
filterValue: ''
},
set: () => {}
}
set
是一个空函数,定义在ContextProviderComponent
中(往上看)。我如何(如果可能)直接在上下文值中定义它,以便:
const defaultContextValue = {
data: {
filterBy: 'year',
isOptionClicked: false,
filterValue: ''
},
test: 'hi',
set: (newData) => {
//directly modify defaultContextValue.data with newData
}
}
最佳答案
您无需同时使用 <Context.Consumer>
和 useContext
钩。
通过使用useContext
钩子(Hook)你可以访问存储在 Context 中的值。
关于您的具体示例,在 Visuals 组件中使用上下文的更好方法如下:
import React, { useContext } from "react";
import Context from "./context";
const Visuals = () => {
const filterByYear = "year";
const filterByTheme = "theme";
const { data, set } = useContext(Context);
const { filterBy, isOptionClicked, filterValue } = data;
const works =
filterBy === filterByYear
? "filter nodes by year"
: "filter nodes by theme";
return (
<div noFooter="true">
<div>
{data.filterBy === filterByYear ? <h1>Year</h1> : <h1>Theme</h1>}
the value for the 'works' variable is: {works}
<button onClick={() => set({ filterBy: "theme" })}>
Filter by theme
</button>
<button onClick={() => set({ filterBy: "year" })}>
Filter by year
</button>
</div>
</div>
);
};
export default Visuals;
此外,您似乎没有使用 works
组件中的变量可能是您未获得所需结果的另一个原因。
您可以查看使用上述 useContext
实现的工作示例这与您在 sandbox 中的示例有些相似
希望这有帮助。
关于javascript - 为什么 `useContext` 不重新渲染我的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59828215/
最近进入一个项目,在react中的useContext看到了以前没见过的东西。 项目中的全局状态使用它发送到上下文的钩子(Hook),然后当稍后在全局状态上调用该钩子(Hook)时,全局状态是可访问的
我使用了一个结构 React Hooks .它基于全局 Context包含 reducer 的组合(如在 Redux 中)。 另外,我广泛使用custom hooks分离逻辑。 我有一个包含异步 AP
在 React 18.1.0 和 React-Dom 18.1.0 中使用 @mui/material 时,我遇到了情感和 react 之间的一系列兼容性问题。这很奇怪,因为我实际上安装了最新版本的
我试图弄清楚如何正确使用 React Context。我对尝试从函数组件外部访问 Context 的问题感到困惑。我收到错误: Line 9:18: React Hook "useContext" i
努力学习如何使用 react 钩子(Hook) .我用 创建上下文 我想将状态和功能一起转移到其他组件,但我需要有关如何执行此操作的帮助。我也想问这样做是否有意义。 事实上,我可以使用 来更新状态设置
我有两个组件 Parent 和 Child,我想将上下文从 Parent 导出到 Child,但这会导致循环依赖。 例如,考虑 Parent.js 是 import {Child} from './C
我对 React 非常着迷,但我遇到了一个关于 useContext 的大问题。真正了解它的内部工作原理是相当令人困惑的。就像它神奇地工作一样。 所以我的主模块中有这样的: export const
更新配置文件时,profile.name 会通过导航链接 (Navigation.js) 中的 useContext() 显示。但是,一旦页面刷新或注销期间,profile.name 就会被清除,pr
我试图以最简单的方式设置 useContext,但它一直返回 undefined。 我已经检查了好几次,但仍然无法破译我遗漏的内容。 上下文.js: import React from 'react'
更新配置文件时,profile.name 会通过导航链接 (Navigation.js) 中的 useContext() 显示。但是,一旦页面刷新或注销期间,profile.name 就会被清除,pr
我试图以最简单的方式设置 useContext,但它一直返回 undefined。 我已经检查了好几次,但仍然无法破译我遗漏的内容。 上下文.js: import React from 'react'
我遇到了一个非常令人沮丧的问题,我不知道发生了什么。我有一个简单的上下文,如下所示: import React, { useState, createContext } from "react"; e
我正在尝试掌握 React 中新的 useContext 函数。在无状态功能组件中效果很好。例如: import React from 'react'; import LocaleContext fr
如果我在 Comp1.js const Comp1 = () => { const globalTheme = new createContext() return (
我无法弄清楚为什么我的 useContext 没有在这个函数中被调用: import { useContext } from "react"; import { MyContext } from ".
我在子组件中有一个按钮 AddMore.js它在列表中添加了更多项目,但它不会重新呈现呈现该列表的其他子组件 Pig.js .我认为我的设置会起作用,因为我使用 NextJS 框架以类似的方式设置了上
你好 我正在尝试进行菜单切换,其中我有一个以 false 作为初始值的变量,使用 react createContext 和 useContext Hook ,我将初始状态设置为 true // us
我有问题,我已经设置了 useContext与 useState提供程序中的值,但是当我导入它们并尝试更改值时,它会在本地更改而不是全局更改! 登录.js import { UserContext }
我正在尝试使用 React Context 来管理我的项目的状态,但这次我似乎无法让它适用于我的 CRA 代码库,而我在其他项目上进行了成功的尝试。 useContext 返回未定义,因此我无法访问上
我是 useContext 的新手钩子(Hook)并试图找出我做错了什么......没有顶级导入,这就是我的代码的样子: 所以我的项目的根是这样的: export default function A
我是一名优秀的程序员,十分优秀!