【问题标题】:Change the state of an element to show an array of Components after API call在 API 调用后更改元素的状态以显示组件数组
【发布时间】:2021-11-13 17:55:43
【问题描述】:

我最近学习了 Next.js,在进入任何后端之前,我查看了 React 和许多需要它的东西。

简而言之,我构建了一个表单,它将接受用户的输入,在 API 中使用它并返回一个 JSON 对象,它将编辑我稍后将展示的一些组件。所以我使用了状态。 我使用辅助变量来设置布尔状态,一旦我的组件将被编辑,该状态将设置为 true。现在,我的组件存储在一个数组中,稍后我将在它被编辑后显示。这是代码

为避免混淆,showResults 是另一种按预期工作的状态。我的问题在于 showMatch 和 setShowMatch

function Form() {

    // adding state to the HeadingText Component to hide it once the user presses the Search button
    const [showResults, setShowResults] = React.useState(true)
    
    // adding state to the auxiliary variable to show my array later after edit
    const [showMatch, setShowMatch] = React.useState(false)

    let matches = []

    // adding the form handling section, with async event to query the API
    const registerUser = async event => {
        event.preventDefault() // don't redirect the page

        // hiding the Component HeadingText, so we show only the data of the games
        setShowResults(false)

        // calling the API in api/register, passing the link of the game or anything we would like to pass
        const res = await fetch('/api/register', {
            body: JSON.stringify({ matchLink: event.target.matchLink.value }),
            headers: { 'Content-Type': 'application/json' },
            method: 'POST'
        })

        //querying the real API, printing out the result
        const result = await res.json()
        console.log(result)

        //preparing my array of components
        for (let i = 0; i < 3; i++) {
            matches.push(<Match
                title = { `game   ${i} `}
                nOfGame = {i}
                game = {result.rounds[i]}
            />);
        }

        setShowMatch(true);
        console.log('I have changed the state, I check if it is true or false, if true: print my array, else: print null')
        console.log(showMatch ? matches : null)
        console.log('I will print my array to double check it\'s value')
        console.log(matches)
    }

    return (
        <>
            { /* Showing or not the component Heading Text */ }
            { showResults ? <HeadingText /> : null }
            
            <div className="form-container">
                <form onSubmit={registerUser}>
                    <input type="text" name="matchLink" id="textFiledId" placeholder="insert a demo" />
                    <input type="submit" value="Search" name="subDemo" />
                </form>
            </div>

            { /* Showing or not the component of the match */ }
            <div className="match-holder">
                { showMatch ? matches : null } 
            </div>

            <p>{matches.length}</p> {/* This should be 0 */ }
        </>
    )
}

export default Form

我不明白如何才能显示我的组件数组,因为控制台https://imgur.com/a/7JP7Jmy 中的这条消息告诉我我的数组已满是组件。我 100% 确定我遗漏了一些东西,但是在浏览了 React 的状态文档一段时间后,我找不到有帮助的示例

(我看过Correct modification of state arrays in React.js的一个问题)

【问题讨论】:

    标签: arrays reactjs next.js state


    【解决方案1】:

    您在组件中使用了本地非状态变量matches,这意味着无论您如何在registerUser 函数中更新它,每次有状态变量更新时,都会触发重新渲染和@987654323 @ 将再次被初始化为[]

    你需要的是一个初始化为[]的新状态变量,你可以在你的registerUser函数中设置它。除非明确更改,否则它将在重新渲染时保留其值。

    将组件存储在 state 中会影响性能,而不是将提到的组件数组所需的 props 存储为 state 中的对象数组,并使用它渲染您的组件。

    这是一个示例实现

    function Form() {
    
        // adding state to the HeadingText Component to hide it once the user presses the Search button
        const [showResults, setShowResults] = React.useState(true)
    
        const [matches, setMatches] = React.useState([])
    
        // adding the form handling section, with async event to query the API
        const registerUser = async event => {
            event.preventDefault() // don't redirect the page
    
            // hiding the Component HeadingText, so we show only the data of the games
            setShowResults(false)
    
            // calling the API in api/register, passing the link of the game or anything we would like to pass
            const res = await fetch('/api/register', {
                body: JSON.stringify({ matchLink: event.target.matchLink.value }),
                headers: { 'Content-Type': 'application/json' },
                method: 'POST'
            })
    
            //querying the real API, printing out the result
            const result = await res.json()
            console.log(result)
    
            let nmatch = []
    
            //preparing my array of components
            for (let i = 0; i < 3; i++) {
                nmatch.push({
                    title: `game   ${i} `
                    nOfGame: i
                    game: result.rounds[i]
                });
            }
            setMatches(nmatch)
        }
    
        return (
            <>
                { /* Showing or not the component Heading Text */ }
                { showResults ? <HeadingText /> : null }
    
                <div className="form-container">
                    <form onSubmit={registerUser}>
                        <input type="text" name="matchLink" id="textFiledId" placeholder="insert a demo" />
                        <input type="submit" value="Search" name="subDemo" />
                    </form>
                </div>
    
                { /* Showing or not the component of the match */ }
                <div className="match-holder">
                    { matches.length > 0 && (
                      matches.map(m => (
                        <Match
                          key={m.title}
                          {...m}
                        />
                      ))
                    )}
                </div>
                <p>{matches.length}</p> {/* This should be 0 */ }
            </>
        )
    }
    
    export default Form
    

    【讨论】:

    • 所以这里的代码设置了一个空数组作为状态,我将在 registerUser 函数中调用 API 后进行更改。一旦完成并且我有了我的数据,它会改变数组的状态并重新渲染它吗?这是正确的吗?
    • 是的。这是正确的。
    • 感谢您的示例和解释,这帮助我解决了问题并更正了我的代码,很高兴您帮助了我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 2018-06-11
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    相关资源
    最近更新 更多