React:sub.component 不在 main.component 上重新渲染
React: sub.component not re-rendering on main.component
我刚开始学习 React,我遇到了以下问题:SubComponent 在更新状态时没有重新渲染数据。
主组件是视图网页,用于保存所有子组件,逻辑组件管理所有功能,而这个子组件是一个较小的HTML,用于呈现其中一个功能。
主要组件:
import LogicComponent from "./LogicComponent";
import SubComponent from "./SubComponent";
export default function Main() {
const { getMaintenance } = LogicComponent()
return (
<>
<div onclick={getMaintenance}>CLICK ME</div>
<SubComponent/>
</>
)
}
逻辑组件:
export default function LogicComponent() {
const [activeMaintenance, setActiveMaintenance] = useState([]);
async function getMaintenance() {
getDocs(collection(db, `/maintenance`))
.then((response) => {
setActiveMaintenance(
response.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}))
);
})
.catch((error) => {
console.log(error);
});
}
return {
getMaintenance,
activeMaintenance,
}
}
子组件
import LogicComponent from "./LogicComponent";
export default function SubComponent() {
const { activeMaintenance } = LogicComponent();
return (
<>
{activeMaintenance.map((fileData) => (
<div key={fileData.id}>{fileData.info}</div>
))}
</>
)
}
每当 点击我 按钮被触发时,子组件上的数据不会更新,即使正确登录到控制台也是如此。
如果我将 SubComponent 代码放入 MainComponent,它会毫无问题地更新。
・我想知道的是,为什么SubComponent接收到数据后没有重新渲染?
此外,我们非常欢迎任何 React 编程建议。
问题
如评论中所述,您有 2 个 LogicComponent 实例 - 一个在 SubComponent 中,一个在 Main 中。将其想象成具有 class 的 2 个实例 - 每个实例中保存的状态是完全独立的。当您从 Main 调用 getMaintenance 时,您更新了保留在 Main 中的 LogicComponent 实例的状态。 SubComponent 的实例未更新。
解决方案 1
使当前设置正常工作的最简单更改如下:
function SubComponent({ activeMaintenance }) {
return (
<>
{activeMaintenance.map((fileData) => (
<div key={fileData.id}>{fileData.info}</div>
))}
</>
);
}
function Main() {
const { getMaintenance, activeMaintenance } = LogicComponent();
return (
<>
<button onClick={getMaintenance}>CLICK ME</button>
<SubComponent activeMaintenance={activeMaintenance} />
</>
);
}
允许 Main 容纳唯一的 LogicComponent 实例,并将 activeMaintenance 作为 prop 向下传递给 SubComponent。这只是几行更改。这是一个有效的 CodeSandbox(用虚假承诺替换您的数据库调用)。
解决方案 2
您似乎渴望共享状态,在这种情况下您可能需要查看 Context。
评论中的另一个注释值得 re-mentioning,您应该考虑将 LogicComponent 重命名为 useMaintenance,因为它本质上是一个 custom hook.
Here 是一个有效的 CodeSandbox,展示了您的应用程序的简单共享全局状态可能是什么样子(使用上下文和挂钩)。
我刚开始学习 React,我遇到了以下问题:SubComponent 在更新状态时没有重新渲染数据。
主组件是视图网页,用于保存所有子组件,逻辑组件管理所有功能,而这个子组件是一个较小的HTML,用于呈现其中一个功能。
主要组件:
import LogicComponent from "./LogicComponent";
import SubComponent from "./SubComponent";
export default function Main() {
const { getMaintenance } = LogicComponent()
return (
<>
<div onclick={getMaintenance}>CLICK ME</div>
<SubComponent/>
</>
)
}
逻辑组件:
export default function LogicComponent() {
const [activeMaintenance, setActiveMaintenance] = useState([]);
async function getMaintenance() {
getDocs(collection(db, `/maintenance`))
.then((response) => {
setActiveMaintenance(
response.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}))
);
})
.catch((error) => {
console.log(error);
});
}
return {
getMaintenance,
activeMaintenance,
}
}
子组件
import LogicComponent from "./LogicComponent";
export default function SubComponent() {
const { activeMaintenance } = LogicComponent();
return (
<>
{activeMaintenance.map((fileData) => (
<div key={fileData.id}>{fileData.info}</div>
))}
</>
)
}
每当 点击我 按钮被触发时,子组件上的数据不会更新,即使正确登录到控制台也是如此。
如果我将 SubComponent 代码放入 MainComponent,它会毫无问题地更新。
・我想知道的是,为什么SubComponent接收到数据后没有重新渲染?
此外,我们非常欢迎任何 React 编程建议。
问题
如评论中所述,您有 2 个 LogicComponent 实例 - 一个在 SubComponent 中,一个在 Main 中。将其想象成具有 class 的 2 个实例 - 每个实例中保存的状态是完全独立的。当您从 Main 调用 getMaintenance 时,您更新了保留在 Main 中的 LogicComponent 实例的状态。 SubComponent 的实例未更新。
解决方案 1
使当前设置正常工作的最简单更改如下:
function SubComponent({ activeMaintenance }) {
return (
<>
{activeMaintenance.map((fileData) => (
<div key={fileData.id}>{fileData.info}</div>
))}
</>
);
}
function Main() {
const { getMaintenance, activeMaintenance } = LogicComponent();
return (
<>
<button onClick={getMaintenance}>CLICK ME</button>
<SubComponent activeMaintenance={activeMaintenance} />
</>
);
}
允许 Main 容纳唯一的 LogicComponent 实例,并将 activeMaintenance 作为 prop 向下传递给 SubComponent。这只是几行更改。这是一个有效的 CodeSandbox(用虚假承诺替换您的数据库调用)。
解决方案 2
您似乎渴望共享状态,在这种情况下您可能需要查看 Context。
评论中的另一个注释值得 re-mentioning,您应该考虑将 LogicComponent 重命名为 useMaintenance,因为它本质上是一个 custom hook.
Here 是一个有效的 CodeSandbox,展示了您的应用程序的简单共享全局状态可能是什么样子(使用上下文和挂钩)。