React 上下文值已更新,但组件不会重新呈现
React Context value gets updated, but component doesn't re-render
此 Codesandbox 目前只有移动样式
我目前有一个基于项目状态呈现的项目列表。
目标:当用户单击模式内的导航按钮时,它会更新上下文中的状态类型。另一个名为 SuggestionList 的组件通过 useContext 使用上下文并呈现出设置为新状态的项目。
问题:上下文中的值确实正在更新,但是使用上下文的 SuggestionList 组件没有根据上下文中的状态使用新的项目列表重新呈现。
这似乎是一个常见问题:
我已经尝试了很多来自不同帖子的建议,但我就是不明白为什么我的 SuggestionList 组件没有在上下文中的值更改时重新呈现。我希望有人能给我一些见解。
Context.js
// CONTEXT.JS
import { useState, createContext } from 'react';
export const RenderTypeContext = createContext();
export const RenderTypeProvider = ({ children }) => {
const [type, setType] = useState('suggestion');
const renderControls = {
type,
setType,
};
console.log(type); // logs out the new value, but does not cause a re-render in the SuggestionList component
return (
<RenderTypeContext.Provider value={renderControls}>
{children}
</RenderTypeContext.Provider>
);
};
SuggestionPage.jsx
// SuggestionPage.jsx
export const SuggestionsPage = () => {
return (
<>
<Header />
<FeedbackBar />
<RenderTypeProvider>
<SuggestionList />
</RenderTypeProvider>
</>
);
};
SuggestionList.jsx
// SuggestionList.jsx
import { RenderTypeContext } from '../../../../components/MobileModal/context';
export const SuggestionList = () => {
const retrievedRequests = useContext(RequestsContext);
const renderType = useContext(RenderTypeContext);
const { type } = renderType;
const renderedRequests = retrievedRequests.filter((req) => req.status === type);
return (
<main className={styles.container}>
{!renderedRequests.length && <EmptySuggestion />}
{renderedRequests.length &&
renderedRequests.map((request) => (
<Suggestion request={request} key={request.title} />
))}
</main>
);
};
Button.jsx
// Button.jsx
import { RenderTypeContext } from './context';
export const Button = ({ handleClick, activeButton, index, title }) => {
const tabRef = useRef();
const renderType = useContext(RenderTypeContext);
const { setType } = renderType;
useEffect(() => {
if (index === 0) {
tabRef.current.focus();
}
}, [index]);
return (
<button
className={`${styles.buttons} ${
activeButton === index && styles.activeButton
}`}
onClick={() => {
setType('planned');
handleClick(index);
}}
ref={index === 0 ? tabRef : null}
tabIndex="0"
>
{title}
</button>
);
};
谢谢
一夜好眠,终于解决了。当你累了的时候,你会想念什么,这真是太神奇了。
我没有意识到我放置的是与 child 本身相同的提供程序。一旦我删除了嵌套在自身中的 child 提供程序,并将“parent”提供程序向上提升了一点,一切都开始工作了。
所以问题不是使用上下文的组件没有更新,而是我放置的提供程序相互冲突。我忘记了我的组件树。愚蠢的错误。
这个故事的寓意是,累了会让你看不到解决办法。好好休息。
此 Codesandbox 目前只有移动样式
我目前有一个基于项目状态呈现的项目列表。
目标:当用户单击模式内的导航按钮时,它会更新上下文中的状态类型。另一个名为 SuggestionList 的组件通过 useContext 使用上下文并呈现出设置为新状态的项目。
问题:上下文中的值确实正在更新,但是使用上下文的 SuggestionList 组件没有根据上下文中的状态使用新的项目列表重新呈现。
这似乎是一个常见问题:
我已经尝试了很多来自不同帖子的建议,但我就是不明白为什么我的 SuggestionList 组件没有在上下文中的值更改时重新呈现。我希望有人能给我一些见解。
Context.js
// CONTEXT.JS
import { useState, createContext } from 'react';
export const RenderTypeContext = createContext();
export const RenderTypeProvider = ({ children }) => {
const [type, setType] = useState('suggestion');
const renderControls = {
type,
setType,
};
console.log(type); // logs out the new value, but does not cause a re-render in the SuggestionList component
return (
<RenderTypeContext.Provider value={renderControls}>
{children}
</RenderTypeContext.Provider>
);
};
SuggestionPage.jsx
// SuggestionPage.jsx
export const SuggestionsPage = () => {
return (
<>
<Header />
<FeedbackBar />
<RenderTypeProvider>
<SuggestionList />
</RenderTypeProvider>
</>
);
};
SuggestionList.jsx
// SuggestionList.jsx
import { RenderTypeContext } from '../../../../components/MobileModal/context';
export const SuggestionList = () => {
const retrievedRequests = useContext(RequestsContext);
const renderType = useContext(RenderTypeContext);
const { type } = renderType;
const renderedRequests = retrievedRequests.filter((req) => req.status === type);
return (
<main className={styles.container}>
{!renderedRequests.length && <EmptySuggestion />}
{renderedRequests.length &&
renderedRequests.map((request) => (
<Suggestion request={request} key={request.title} />
))}
</main>
);
};
Button.jsx
// Button.jsx
import { RenderTypeContext } from './context';
export const Button = ({ handleClick, activeButton, index, title }) => {
const tabRef = useRef();
const renderType = useContext(RenderTypeContext);
const { setType } = renderType;
useEffect(() => {
if (index === 0) {
tabRef.current.focus();
}
}, [index]);
return (
<button
className={`${styles.buttons} ${
activeButton === index && styles.activeButton
}`}
onClick={() => {
setType('planned');
handleClick(index);
}}
ref={index === 0 ? tabRef : null}
tabIndex="0"
>
{title}
</button>
);
};
谢谢
一夜好眠,终于解决了。当你累了的时候,你会想念什么,这真是太神奇了。
我没有意识到我放置的是与 child 本身相同的提供程序。一旦我删除了嵌套在自身中的 child 提供程序,并将“parent”提供程序向上提升了一点,一切都开始工作了。
所以问题不是使用上下文的组件没有更新,而是我放置的提供程序相互冲突。我忘记了我的组件树。愚蠢的错误。
这个故事的寓意是,累了会让你看不到解决办法。好好休息。