【问题标题】:React-native application hanging when updating a parent from a child从孩子更新父母时,React-native 应用程序挂起
【发布时间】:2022-01-09 22:26:20
【问题描述】:

我在这里有一个奇怪的行为。

我正在尝试从孩子更新父组件。

因此,我为孩子准备了这样的东西:

const LabelList = ({editable, boardLabels, cardLabels, size='normal', udpateCardLabelsHandler}) => {
     return (
            <DropDownPicker
                labelStyle={{
                    fontWeight: "bold"
                  }}
                badgeColors={badgeColors}
                showBadgeDot={false}
                items={items}
                multiple={true}
                open={open}
                onChangeValue={(value) => udpateCardLabelsHandler(value)}
                value={value}
                setOpen={setOpen}
                setValue={setValue} />
        )
}

对于父母来说,这样的事情:

const CardDetails = () => {
    const [updatedCardLabels, setUpdatedCardLabels] = useState([])
    const [card, setCard] = useState({})
    const [editMode, setEditMode] = useState(false)

    // Handler to let the LabelList child update the card's labels
    const udpateCardLabelsHandler = (values) => {
        const boardLabels = boards.value[route.params.boardId].labels
        const labels = boardLabels.filter(label => {
            return values.indexOf(label.id) !== -1
        })    
        console.log('updated labels',labels)
        setUpdatedCardLabels(labels)
    }

    return (
        <View style={{zIndex: 10000}}>
              <Text h1 h1Style={theme.title}>
                   {i18n.t('labels')}
              </Text>
              <LabelList 
                    editable = {editMode}
                    boardLabels = {boards.value[route.params.boardId].labels}
                    cardLabels = {card.labels}
                    udpateCardLabelsHandler = {udpateCardLabelsHandler} />
            </View>
     )

而且,这根本行不通:只要我尝试更改 DropDownPicker 中的某些内容,应用程序就会挂起。 console.log 语句甚至没有被执行,我的 expo 控制台中也没有出现任何错误。

奇怪的是,例如,如果我将updateCardLabels 状态更改为布尔值,一切正常(例如:console.log 语句被执行):

const [updatedCardLabels, setUpdatedCardLabels] = useState(false)

// Handler to let the LabelList child update the card's labels
const udpateCardLabelsHandler = (values) => {
    const boardLabels = boards.value[route.params.boardId].labels
    const labels = boardLabels.filter(label => {
        return values.indexOf(label.id) !== -1
    })    
    console.log('updated labels',labels)
    setUpdatedCardLabels(true)
}

请注意,updatedCardLabels 没有在任何地方使用:它是一个虚拟变量,我只是用来调试这个问题(以确保我没有以一些无休止的渲染循环或类似的东西结束)。

为了完整起见,这是labelsconsole.log('updated labels',labels) 行的样子(请不要说我只能在执行setUpdatedCardLabels(true) 时看到此值,否则,当代码执行setUpdatedCardLabels(labels) 时,控制台。 log 语句不执行,如前所述):

updated labels Array [
  Object {
    "ETag": "a95b2566521a73c5edfb7b8f215948bf",
    "boardId": 1,
    "cardId": null,
    "color": "CC317C",
    "id": 9,
    "lastModified": 1621108392,
    "title": "test-label",
  },
]

有人对这种奇怪的行为有解释吗?

最好的问候,

西里尔

【问题讨论】:

  • 除了将updatedCardLabels 值更改为布尔值之外,您还进行了哪些调试?有没有错误?代码堆栈跟踪? updatedCardLabels 状态在哪里使用/引用?似乎udpateCardLabelsHandler 采用values 参数,但您的代码在DropDownPicker 中传递了value 值。 udpateCardLabelsHandler 处理程序中 values 的值是多少?你有没有通过udpateCardLabelsHandler查看它在哪里中断?
  • 您好,感谢您的反馈。我已经更新了我的问题来回答你的问题,但总结如下:在我的 expo 控制台中没有出现一个错误,updatedCardLabels 没有在任何地方使用:这是我为调试这个问题而创建的一个虚拟变量(以确保我并没有以一些无休止的渲染循环或类似的东西结束)。我无法单步执行updateCardLabelsHandler:即使我将console.log 语句放在它的第一行,当setUpdatedCardLabels 将数组作为参数时它也不会执行。
  • 所以只需将setUpdatedCardLabels(labels) 更改为setUpdatedCardLabels(true) 就可以让代码工作?如果您完全删除此行,代码是否可以正常工作?考虑到你说你没有在任何地方使用updatedCardLabels state 值,它似乎没有任何有用的目的。
  • 好吧,updatedCardLabels 在我弄清楚如何更新它之后最终会被使用...
  • 您应该能够将其更新为您想要的任何内容。现在有什么东西在引用它,如果它是一个数组会导致错误?

标签: javascript react-native react-hooks


【解决方案1】:

所以,我发现了问题:这是 DrowpDownPicker 的副作用。

我已经通过改变我的孩子解决了这个问题:

const LabelList = ({editable, boardLabels, cardLabels, size='normal', udpateCardLabelsHandler}) => {

    const [open, setOpen] = useState(false);
    const [value, setValue] = useState(cardLabels.map(item => item.id));

    const theme = useSelector(state => state.theme)

    // Updates parent when value changes
    useEffect(() => {
        if (typeof udpateCardLabelsHandler !== 'undefined') {
            udpateCardLabelsHandler(value)
        }
    }, [value])

        return (
            <DropDownPicker
                labelStyle={{
                    fontWeight: "bold"
                  }}
                badgeColors={badgeColors}
                showBadgeDot={false}
                items={items}
                multiple={true}
                open={open}
                value={value}
                setOpen={setOpen}
                setValue={setValue} />
        )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    相关资源
    最近更新 更多