javascript - 子组件不会重新渲染
问题描述
我正在使用两个功能性反应组件,其中我id
通过道具将单击项目的(状态)向下传递给子组件。
问题
id 确实会在子组件中渲染,但是当父组件中的状态更新时,子组件会创建一个新的渲染,而不是更新之前的渲染。所以例如。子组件显示id
1,当单击另一个项目时,子组件同时显示1和 newid
父类:
import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
import Test from "./test";
const { useState, useCallback } = React;
export default function MyTreeItem(props) {
const [childNodes, setChildNodes] = useState(null);
const [expanded, setExpanded] = React.useState([]);
const [activeItemId, setActiveItemId] = useState();
function fetchChildNodes(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
children: [
{
id: "2",
name: "Calendar"
},
{
id: "3",
name: "Settings"
},
{
id: "4",
name: "Music"
}
]
});
}, 1000);
});
}
const handleChange = (event, nodes) => {
const expandingNodes = nodes.filter(x => !expanded.includes(x));
setExpanded(nodes);
if (expandingNodes[0]) {
const childId = expandingNodes[0];
fetchChildNodes(childId).then(result =>
setChildNodes(
result.children.map(node => <MyTreeItem key={node.id} {...node} />)
)
);
}
};
const renderLabel = item => (
<span
onClick={event => {
console.log(item.id);
setActiveItemId(item.id);
// if you want after click do expand/collapse comment this two line
event.stopPropagation();
event.preventDefault();
}}
>
{item.name}
</span>
);
return (
<div>
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
expanded={expanded}
onNodeToggle={handleChange}
>
{/*The node below should act as the root node for now */}
<TreeItem nodeId={props.id} label={renderLabel(props)}>
{childNodes || [<div key="stub" />]}
</TreeItem>
</TreeView>
<Test test={activeItemId} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyTreeItem id="1" name="Applications" />, rootElement);
儿童班:
import React, { useState, useEffect } from "react";
export default function Test({ test }) {
return <h1>{test}</h1>;
}
解决方案
问题来自 [unexpected] recurrency -setChildNodes
将“树根”组件呈现<MyTreeItem />
为子组件,每个组件都有自己的状态、处理程序等。
您可以通过渲染<TreeItem />
为子级来解决此问题:
setChildNodes(
result.children.map(node => <TreeItem nodeId={node.id} label={renderLabel(node)} /> )
)
推荐阅读
- google-cloud-platform - GCP 云功能 - 在构建/部署期间获取存储源时出错
- javascript - 带有 Snowpack 的 JavaScript 私有类方法
- django - 我可以在 Django 的两列模板中动态放置项目吗?
- aws-lambda - SAM AWS Lambda 工作但在报告超时问题时从不返回
- sql - 如何使用 Oracle PL/SQL 从给定的 Oracle 源表创建十个相似的表
- php - 如何解析来自 Easyship webhook 的响应
- javascript - 使用jquery单击表格中的单元格文本
- html - 指定要在 CSS 类的背景属性中使用的图像
- javascript - 如何在 forEach 中嵌套 forEach 以获取 JavaScript 的总和
- python - AWS 抛出以下错误:“错误的解释器:没有这样的文件或目录”