javascript - 反应子组件不会在更新的父状态上重新渲染
问题描述
我试图找到解决方案,但似乎没有任何效果。我想要做的是创建一个带有复选框的 TreeView 。当您在复选框中选择一个项目时,它会附加一个列表,当您取消选中它时,将其从列表中删除。这一切都有效,但是当我折叠和展开 TreeItem 时遇到的问题是,我失去了选中状态。我尝试通过检查我选择的列表来解决这个问题,但是每当运行 useEffect 函数时,子组件都没有正确的父状态列表。
我有以下父组件。这是与此类似的形式(https://www.youtube.com/watch?v=HuJDKp-9HHc)
export const Parent = () => {
const [data,setData] = useState({
name: "",
dataList : [],
// some other states
})
const handleListChange = (newObj) => {
//newObj : { field1 :"somestring",field2:"someotherString" }
setDataList(data => ({
...data,
dataList: data.actionData.concat(newObj)
}));
return (
{steps.current === 0 && <FirstPage //setting props}
....
{step.current == 3 && <TreeForm dataList={data.dataList} updateList={handleListChange}/>
)
}
Tree 组件是一个 Material UI TreeView,但自定义为包含一个复选框
由于来回传递的数据的大小,每个节点都是从 API 调用动态加载的。(根被加载,然后根据您选择的节点,当时加载子节点)。
我的树类是
export default function Tree(props) {
useEffect(() => {
// call backend server to get roots
setRoots(resp)
})
return (
<TreeView >
Object.keys(root).map(key => (
<CustomTreeNode key={root.key} dataList={props.dataList} updateList={props.updateList}
)))}
</TreeView>
)
CustomTreeNode 定义为
export const CustomTreeNode = (props) => {
const [checked,setChecked] = useState(false)
const [childNodes,setChildNodes] = useState([])
async function handleExpand() {
//get children of current node from backend server
childList = []
for( var item in resp) {
childList.push(<CustomTreeNode dataList={props.dataList} updateList={props.updateList} />)
}
setChildNodes(childList)
}
const handleCheckboxClick () => {
if(!checked){
props.updateList(obj)
}
else{
//remove from list
}
setChecked(!checked)
}
// THIS IS THE ISSUE, props.dataList is NOT the updated list. This will work fine
// if I go to the next page/previous page and return here, because then it has the correct dataList.
useEffect(() => {
console.log("Tree Node Updating")
var isInList = props.dataList.find(function (el) {
return el.field === label
}) !== undefined;
if (isInList) {
setChecked(true);
} else {
setChecked(false)
}
}, [props.dataList])
return ( <TreeItem > {label} </TreeItem> )
}
解决方案
您将 props.data 放在 useEffect 依赖数组中而不是 props.dataList 中,因此当 props.dataList 更改时它不会更新。
编辑:您的选中状态是 CustomTreeNode 类的状态变量。当一棵树被销毁时,该状态变量也被销毁。您需要将检查状态存储在未被破坏的更高组件中,可能作为检查布尔值列表。
推荐阅读
- c# - 在每个请求中,新会话都在 web api 中生成
- ios - Xcode 10.2 中 iPad 的此平台不支持 MGIsDeviceOneOfType
- python - 为什么 AWS 在一台服务器上允许 ListObjects 在另一台服务器上被拒绝
- spring - 如何在 Spring 响应式 WebClient 中返回 Kotlin Coroutines Flow
- mysql - 如何在 SQL 中建立账户
- python - L += [a] 和 L.append(a) 的区别
- android - recyclerview 滚动抖动与滑动图像加载,还包含其他 recylerview、webview 和视频帧
- apache-spark - 如果 Spark 应用程序请求的内存超过集群的内存,会发生什么情况?
- tensorflow - 如何使用 TensorFlow 图像分类模型调用 Google AI Platform API
- javascript - 在搜索框上书写时遇到 axios 问题