useState表现不符合预期

值得

我对useState有问题。editorDataOpen从设定时,可以正确更新openEditorData,而不是从设置时closeEditorData的console.log(“进入档案> closeEditorData()”)达到没有问题。

我在控制台日志中看到的输出是:

  • 渲染
  • 渲染
  • false(第一次设置editorDataOpen)
  • 渲染
  • 渲染
  • 渲染
  • 渲染
  • true(通过单击将editorDataOpen设置为true,这将打开编辑器)
  • 输入配置文件> closeEditorData()(通过另一次点击触发,以关闭编辑器,应将editorDataOpen设置为false,但不设置)
  • 渲染
  • 渲染

就是这样,它永远不会打印出最后一个false,这意味着从不设置editorDataOpen

我今天在此上花了太多时间,但我根本看不出错误在哪里。有人可以帮忙吗?这是有问题的代码:

import React from 'react'
import {withTheme} from 'styled-components'
import {withContext} from '../../context/ContextHOC'
import withLoadingScreen from '../hocs/LoadingScreenHOC'
import {getEditorWidth} from '../../functions/funcEditor'
import {saveImagePlus} from '../../functions/funcDataSaver'
import Submodule from '../ui/Submodule'
import ImageCapsule from '../ui/ImageCapsule'
import EditorImage from '../editors/EditorImage'
import EditorProfileData from '../editors/EditorProfileData'
import Spacer from '../ui/Spacer'
import Table from '../ui/Table'
import ContainerGrid from '../ui/ContainerGrid'
import * as ops from '../../functions/funcStringMath'
import * as parse from '../../functions/funcDataParser'

const Profile = (props) => {

    const s = props.theme.sizes
    const c = props.theme.cards

    const {setLoadingOn, setLoadingOff} = props
    const [image, setImage] = React.useState(props.context.current.modules.me.profile.image)
    const [editorImageOpen, setEditorImageOpen] = React.useState(false)
    const [editorDataOpen, setEditorDataOpen] = React.useState(false)
    
    const openEditorImage = () => setEditorImageOpen(true)
    const openEditorData = () => setEditorDataOpen(true)
    
    const closeEditorImage = () => {
        setEditorImageOpen(false)
        setLoadingOff()
    }

    const closeEditorData = () => {
        console.log('Entering Profile > closeEditorData()')
        setEditorDataOpen(false)
        setLoadingOff()
    }

    React.useEffect(() => console.log(editorDataOpen), [editorDataOpen])

    const updateAfterSavingImage = (img) => {

        setImage({
            url: img.url,
            scale: img.scale,
            position: img.position
        })

        closeEditorImage()

    }

    const handleImageChanged = (img) => {
        
        if (img != undefined){

            setLoadingOn()

            const data = {
                companyId: props.context.current.company.id,
                userId: props.context.current.user.id,
                routeFile: props.context.routes.meProfileImage,
                routeData: props.context.routes.meProfileImageData,
            }
        
            saveImagePlus(img, data, updateAfterSavingImage)

        }
        else {
            console.log('Error: Image received is undefined, cannot save.')
            closeEditorImage()
        }

    }

    const spacer =
        <Spacer
            width = '100%'
            height = {s.spacing.default}
        />

    const unparsedData = props.context.current.modules.me.profile.data
    const parsedData = parse.profileData(props.context.current.modules.me.profile.data)

    console.log('Render')

    return(

        <Submodule
            isMobile = {c.cardsPerRow == 1 ? true : false}
            header = {{
                text: 'Profile',
            }}
            {...props}
        >

            <ImageCapsule 
                onClick = {openEditorImage}
                id = {'container_imageprofile'}
                width = '100%'
                image = {image}
                $nodrag
            />

            {editorImageOpen &&
                <EditorImage
                    open = {editorImageOpen}
                    closeSaving = {handleImageChanged}
                    closeWithoutSaving = {closeEditorImage}
                    image = {image}
                    width = {getEditorWidth(1, c.cardsPerRow, c.card.width, s.spacing.default)}
                    header = {{
                        text: 'Edit Profile Image',
                    }}
                />
            }

            {spacer}
            {spacer}
            
            <ContainerGrid
                // bgcolor = '#C43939'
                width = '100%'
                justify = {s.justify.center}
                onClick = {openEditorData}
                $clickable
            >
            
                <Table
                    $nomouse
                    width = '100%' 
                    data = {parsedData}
                    settings = {{

                        cell: {
                            padleft: s.spacing.default,
                            padright: s.spacing.default,
                            padtop: ops.round((ops.divide([s.spacing.default, 4]))),
                            padbottom: ops.round((ops.divide([s.spacing.default, 4]))),
                        },
                        
                        columns: [
                            {type: 'defaultRight', width: '30%'},
                            {type: 'default', width: '70%'},
                        ]

                    }}
                />

                {editorDataOpen &&
                    <EditorProfileData
                        open = {editorDataOpen}
                        close = {closeEditorData}
                        width = {getEditorWidth(1, c.cardsPerRow, c.card.width, s.spacing.default)}
                        header = {{
                            text: 'Edit Profile Data',
                        }}
                        data = {unparsedData}
                    />
                }

            </ContainerGrid>

            {spacer}
            {spacer}

        </Submodule>

    )
}

export default (
    withTheme(
        withContext(
            withLoadingScreen(
                Profile
            )
        )
    )
)

编辑:这已经由Dehan de Croos解决了,非常感谢!


因此,正如Dehan在下面提到的那样,该事件正在冒泡并在ContainerGrid中触发openEditorData。整个过程令人迷惑不解,因为editorImageOpen可以正常工作,而editorDataOpen却无法正常工作,而且它们都做同样的事情:打开Editor窗口。一旦Dehan解决了问题,我意识到2之间的区别是ImageCapsule内部有一个ClickLayer组件,该组件只是用来捕获单击和回调的。我没有在ContainerGrid上使用ClickLayer,这就是事件能够冒泡的原因。按照Dehan的建议,我通过在ContainerGrid内添加一个ClickLayer来解决,如下所示:

            <ContainerGrid
                // bgcolor = '#C43939'
                width = '100%'
                justify = {s.justify.center}
                // onClick = {openEditorData}
                $clickable
            >

                <ClickLayer
                    onClick = {openEditorData}    
                />
            
                <Table
                    $nomouse
                    width = '100%' 
                    data = {parsedData}
                    settings = {{

                        cell: {
                            padleft: s.spacing.default,
                            padright: s.spacing.default,
                            padtop: ops.round((ops.divide([s.spacing.default, 4]))),
                            padbottom: ops.round((ops.divide([s.spacing.default, 4]))),
                        },
                        
                        columns: [
                            {type: 'defaultRight', width: '30%'},
                            {type: 'default', width: '70%'},
                        ]

                    }}
                />

                {editorDataOpen &&
                    <EditorProfileData
                        open = {editorDataOpen}
                        close = {closeEditorData}
                        width = {getEditorWidth(1, c.cardsPerRow, c.card.width, s.spacing.default)}
                        header = {{
                            text: 'Edit Profile Data',
                        }}
                        data = {unparsedData}
                    />
                }

            </ContainerGrid>
德汉·德·克鲁斯

最好有一个有效的代码片段来对此进行诊断,但是很有可能该事件可能会使组件树冒泡并在openEditorData此处触发该事件。

              <ContainerGrid
                // bgcolor = '#C43939'
                width = '100%'
                justify = {s.justify.center}
                onClick = {openEditorData}
                $clickable
             >

要对此进行快速检查,请将下面显示的组件移到组件外部<ContainerGrid ... />并检查是否可以解决问题。

为了在此处进行说明,应该进行代码移动,以使<EditorProfileData ... />永远不会作为以下内容的子组件出现: <ContainerGrid ... />

            {editorDataOpen &&
                <EditorProfileData
                    open = {editorDataOpen}
                    close = {closeEditorData}
                    width = {getEditorWidth(1, c.cardsPerRow, c.card.width, s.spacing.default)}
                    header = {{
                        text: 'Edit Profile Data',
                    }}
                    data = {unparsedData}
                />
            }

如果现在它可以正常工作,并且您非常需要维护上述组件的层次结构/结构。您可以调用stopPropegation,但您需要随身携带本机JS事件。为了说明如何执行此操作,我需要了解<EditorProfileData ... />外观。但是,假设close道具确实返回了本地点击事件作为回调,则此修复程序将类似于以下内容。

            {editorDataOpen &&
                <EditorProfileData
                    open = {editorDataOpen}
                    //close = {closeEditorData}

                    // If close provides the native event use following
                    close = { e => {
                        e.stopPropagation();
                        closeEditorData();
                    }}

                    width = {getEditorWidth(1, c.cardsPerRow, c.card.width, s.spacing.default)}
                    header = {{
                        text: 'Edit Profile Data',
                    }}
                    data = {unparsedData}
                />
            }

如果不是,我们需要找到原始的onClick事件并传递给该prop回调。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

strpbrk表现不符合预期

来自分类Dev

React useEffect表现不符合预期

来自分类Dev

Cron工作表现不符合预期

来自分类Dev

C ++ 11 std :: condition_variable-notify_one()表现不符合预期吗?

来自分类Dev

带有复选框的Android listview表现不符合预期

来自分类Dev

Coffeescript类的行为不符合预期

来自分类Dev

约束不符合我的预期

来自分类Dev

文件内容不符合预期

来自分类Dev

SSLContext模拟行为不符合预期

来自分类Dev

AtomicInteger增量不符合预期

来自分类Dev

类型n的行为不符合预期

来自分类Dev

面料环境不符合预期

来自分类Dev

Javascript日期比较不符合预期

来自分类Dev

CancellationTokenSource的行为不符合预期

来自分类Dev

引导表不符合预期

来自分类Dev

Opencl减少不符合预期

来自分类Dev

RecyclerView onBindViewHolder位置不符合预期

来自分类Dev

jQuery parseHTML结果不符合预期

来自分类Dev

如果条件不符合预期

来自分类Dev

消毒输入但输出不符合预期

来自分类Dev

WinWaitActive函数的行为不符合预期

来自分类Dev

变量的行为不符合预期

来自分类Dev

isinstance()的行为不符合我的预期

来自分类Dev

类别订购不符合预期

来自分类Dev

cublas矩阵乘法不符合预期

来自分类Dev

jQuery remove()行为不符合预期

来自分类Dev

SqlDataReader结果不符合预期

来自分类Dev

页脚宽度不符合预期

来自分类Dev

Excel OR函数的行为不符合预期