反应树组件更新状态失败

时间:2019-11-13 14:51:35

标签: reactjs setstate

问题

我是React的新手,在构建树组件作为个人边项目时,我遇到了一些问题。当我单击树形结构时,它应该会塌陷或塌陷,但无法按预期工作。当我重定向到另一个组件并重定向回它时,它起作用了,我试图添加断点进行调试,树组件的数据已按预期进行了更改,但我不知道为什么。

代码

树组件

const Tree: React.FC<Props> = ({ data }) => {
  const [stateData, setStateData] = useState({ data: data })

  let keyNodeMap: KeyNodeMap = {}

  useEffect(() => {
    bindKeyMap()
  },[])

  const bindKeyMap = () => {
    let data = stateData.data
    keyNodeMap[data.key] = data
    if (data.children && data.children.length) {
      walk(data.children, data)
    }
  }


  const walk = (children: TreeData[], parent: TreeData): void => {
    children.forEach((child: TreeData) => {
      child.parent = parent
      keyNodeMap[child.key] = child
      if (child.children && child.children.length > 0) {
        walk(child.children, child)
      }
    })
  }

  const onCollapse = (key: string) => {
    let data = keyNodeMap[key]
    if (data) {
      let { children } = data
      if (children) {
        data.collapsed = !data.collapsed
        data.children = data.children || []
        setStateData(stateData)
        console.log(stateData);
      } else {
        // todo
      }
    }
  }

  const onCheck = (key: string) => {
    let data = keyNodeMap[key]
    if (data) {
      data.checked = !data.checked
      if (data.checked) {
        checkChildren(data.children, true)
        checkParent(data.parent)
      } else {
        checkChildren(data.children, false)
        checkParent(data.parent)
      }
    }
  }

  const checkParent = (parent: TreeData) => {
    while (parent) {
      parent.checked = parent.children.every((item: TreeData) => item.checked)
      parent = parent.parent
    }
  }

  const checkChildren = (children: TreeData[] = [], checked: boolean) => {
    children.forEach((item: TreeData) => {
      item.checked = checked
      checkChildren(item.children, checked)
    })
  }

  const renderTree = ({ getPrefixCls }: ConfigConsumerProps) => {
    const prefixCls = getPrefixCls('tree')
    return (
      <div className={`${prefixCls}`}>
        <div className='tree-nodes'>
          <TreeNode data={data} onCollapse={onCollapse} onCheck={onCheck} />
        </div>
      </div>
    )
  }

  return <ConfigConsumer>{renderTree}</ConfigConsumer>
}

树节点

const TreeNode: React.FC<NodeProps> = ({
  data,
  onCollapse,
  onCheck
}) => {
  let children = data.children
  return (
    <div className='tree-node'>
      <div className='inner'>
        {children && children.length > 0 ? (
          <span
            onClick={() => {
              onCollapse(data.key)
            }}
          >
            {data.collapsed ? <FaCaretRight /> : <FaCaretDown />}
          </span>
        ) : (
            ''
          )}
        {data.type === 'folder' ? data.collapsed ? <FaFolder /> : <FaFolderOpen /> : <FaFileAlt />}
        <span>{data.name}</span>
      </div>
      {
        <div className='children'>
          {children &&
            children.length > 0 &&
            !data.collapsed &&
            children.map(child => {
              return <TreeNode data={child} key={child.key} onCollapse={onCollapse} onCheck={onCheck} />
            })}
        </div>
      }
    </div>
  )
}

export default TreeNode

链接

IIF

任何帮助将不胜感激!

0 个答案:

没有答案