我对useState有问题。editorDataOpen从设定时,可以正确更新openEditorData,而不是从设置时closeEditorData。行的console.log(“进入档案> closeEditorData()”)达到没有问题。
我在控制台日志中看到的输出是:
就是这样,它永远不会打印出最后一个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] 删除。
我来说两句