For循环仅适用于带有React钩子的第二个循环

时间:2019-08-31 03:32:29

标签: javascript reactjs react-hooks

我有一个要添加标签的项目,类似于此站点。我想先检查用户是否已经选择了标签。我有一个for循环,以查看添加的标签是否等于已经存在的标签。

如果我创建一个名为Jack的标签,它将正常工作。如果我创建另一个名为Jack的标签,现在我有两个Jacks(不好)。在第三次尝试时,它不会添加另一个Jack(好)。

这是我的相关代码。我也添加了控制台。我的useState setTagAlreadyThere on在第三次尝试之前将被忽略,而在第二次尝试时应变为true。我在这里做什么错了?

const [tagsFound, setTagsFound] = useState([])
const [tagsAdded, setTagsAdded] = useState([])    
const [tagAlreadyThere, setTagAlreadyThere] = useState(false)

const gatherTags = (tags) => {
    setTagAlreadyThere(false)
    console.log(tagAlreadyThere)

    if (tagsAdded.length === 0) {
        setTagsAdded([...tagsAdded, tags]);
    } else {
        console.log(tagsAdded)

        for (let i = 0; i < tagsAdded.length; i++) {
            console.log(tagsAdded[i])

            if (tags === tagsAdded[i]) {
                console.log(tagsAdded[i])
                console.log(tags)
                setTagAlreadyThere(true)
                console.log(tagAlreadyThere)
            }
        }
        console.log(tagAlreadyThere)
        if (tagAlreadyThere === false) {
            setTagsAdded([...tagsAdded, tags]);
            console.log(tagsAdded)
        } else {
            return
        }
    }

    setPostTag('')
}

控制台。

TagAdder.tsx:9 jack
postarticle.tsx:64 false
postarticle.tsx:69 ["jack"]
postarticle.tsx:72 jack
postarticle.tsx:75 jack
postarticle.tsx:76 jack
postarticle.tsx:78 false
postarticle.tsx:81 false
postarticle.tsx:84 ["jack"]
post.tsx:6 {}
postarticle.tsx:92 (2) ["jack", "jack"]
post.tsx:6 {}
postarticle.tsx:

92

2 个答案:

答案 0 :(得分:2)

没有冒犯,但您的代码包含许多不必要的内容。

为什么会这样。因为您tagAlreadyThere尚未更新。您正在检查它的价值。

const gatherTags = (tags) => {
    if (!tagsAdded.inlcudes(tags)) {
      setTagsAdded([...tagsAdded, tags]);
      setPostTag('')
    }
}

不需要const [tagAlreadyThere, setTagAlreadyThere] = useState(false)

答案 1 :(得分:1)

我将向您介绍为什么此代码会引起很多问题,没有冒犯性。

首先,您要在循环内部同步调用一个钩子,因为 React.useState 钩子是异步的,就像基于类的 this.setState 一样,它会批量更新以获取性能。

我在代码沙箱中有一个示例:Calling Hooks Sync and Async

第二个是如果您的新状态是从前一个状态计算得出的,请使用回调样式,因为您可以访问更新的前一个状态,例如:

setTagsAdded(prevTagsAdded => [...prevTagsAdded, tags])

您可以在此处查看文档:{​​{3}}

希望这会有所帮助!