reactjs - ReactJS 挂钩 useContext 问题
问题描述
我有点喜欢 ReactJS,我正在尝试将 useContext 与钩子一起使用,但我遇到了一些麻烦。我已经阅读了几篇文章,但我无法理解。
我理解它的目的,但我不知道如何使它正常工作。如果我是正确的,那么目的是能够避免将道具传递给每个孩子,并能够在组件树的任何深度访问来自公共提供者的值。这包括函数和状态值。如果我错了,请纠正我。
我一直在使用以下文件进行测试。这是ManagerContext.js
文件:
import { createContext } from 'react';
const fn = (t) => {
console.log(t);
}
const ctx = createContext({
title: 'This is a title',
editing: false,
fn: fn,
})
let ManagerContext = ctx;
export default ManagerContext;
然后我有LessonManager.js
在我的主应用程序中使用的文件:
import React from 'react';
import LessonMenu from './LessonMenu.js';
export default function LessonManager() {
return (
<LessonMenu />
)
}
最后是LessonMenu.js
:
import React from 'react';
import 'rsuite/dist/styles/rsuite.min.css';
import ManagerContext from './ManagerContext.js';
export default function LessonMenu() {
const value = React.useContext(ManagerContext);
return (
<div>
<span>{value.title}</span>
<button
onClick={()=>value.fn('ciao')}
>click</button>
<button
onClick={()=>value.title = 'new title'}
>click</button>
</div>
)
}
在 LessonMenu.js 文件中onClick={()=>value.fn('ciao')}
可以工作,但 onClick={()=>value.title = 'new title'}
不会重新渲染组件。
我知道出了点问题,但是有人可以让我更清楚吗?
解决方案
为了进行重新渲染,某处的某些组件必须调用 setState。您的代码没有这样做,因此不会发生渲染。
您为 ManagerContext 所做的设置会创建一个默认值,但只有在您不在组件树中呈现任何 ManagerContext.Provider 时才会使用该默认值。这就是你现在正在做的事情,但几乎可以肯定这不是你想要的。您会希望在树的顶部附近有一些组件呈现 ManagerContext.Provider。该组件可以是状态所在的位置,并且在它发送的数据中将是一个或多个设置状态的函数,从而触发重新渲染:
export default function LessonManager() {
const [title, setTitle] = useState('SomeOtherTitle');
const [editing, setEditing] = useState(false);
const value = useMemo(() => {
return {
title,
setTitle,
editing,
setEditing,
log: (t) => console.log(t)
}
}, [title, editing]);
return (
<ManagerContext.Provider value={value} >
<LessonMenu />
</ManagerContext.Provider/>
)
}
// used like:
export default function LessonMenu() {
const value = React.useContext(ManagerContext);
return (
<div>
<span>{value.title}</span>
<button onClick={() => value.log('ciao')}>
click
</button>
<button onClick={() => value.setTitle('new title')}>
click
</button>
</div>
)
}
推荐阅读
- time - bigquery 输出中是否可以有多个时区?
- java - 线程“主”java.util.UnknownFormatConversionException 中的异常:Conversion = ':'
- python - AWS ECS 上容器中的 Scapy 不会下载或创建文件
- android - Xamarin 应用程序在开启暗模式的 Android 设备上自动切换到暗模式
- android - TelephonyManager.getAllCellInfo() 返回 Null 或显示 Nothing
- r - R带有二进制列的新数据框
- javascript - vue 组件没有渲染从后端获取的数据
- bash - Github 自动更新与 cron
- javascript - Express 没有渲染我的 React 前端?
- python - 如何在'\n'处将一个列表分成两个列表?