javascript - 如何在 React 中映射一个 prop,它是一个对象数组

标签 javascript reactjs graphql

我正在尝试将对象数组从 App.js 传递到我的 MenuPage。如果没有 map ,我可以控制台记录我传递的 activities 属性。但是,当我尝试运行 map 时,出现错误,console.log 无法再识别 activities 属性,而是收到多个空数组的 console.log。

此外,这是我的 activities 动态渲染的正确方法吗?我曾经在 MenuPage.js 上有 activities 状态,但每当我添加新事件时,我都必须刷新才能显示新添加的事件。因此,我决定尝试将其移动到其父文件 App.js 中。

map 时出现错误消息

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

如果没有 map ,则显示 activities 属性的控制台日志

{getActivities: Array(5)}
    getActivities: Array(5)
        0: {id: "5e64abc6de157e027c1fc224", name: "Test1", location: "Test1", activityDate: "Test1", description: "Test1", …}
        1: {id: "5e69b103dd9e0b20f8636da9", name: "Test234", location: "Test2", activityDate: "Test2", description: "Test2", …}
        2: {id: "5e6a744eca11a3355cdde03b", name: "test3", location: "test3", activityDate: "test3", description: "test3", …}
        3: {id: "5e6a74c9be805e042057b3b1", name: "test4", location: "test4", activityDate: "test4", description: "test4", …}
        4: {id: "5e6a74e4be805e042057b3b2", name: "test5", location: "test5", activityDate: "test5", description: "test5", …}
        length: 5
__proto__: Array(0)

MenuPage.js

const MenuPage = ({activities}) => {
    const [activity, setActivity] = useState([])

    console.log(activities)

    setActivity(activities.map( (activity) => <ActivityItem activity={activity} />))

App.js

const App = () => {
    const [activities, setActivities] = useState([])

    useEffect( () => {
        GQLClient({}).request(Query.getActivities, null).then( ({getActivities}) => {
            setActivities({getActivities})
        })
    }, [])

    const Load = (props, page) => {
        if (user.token === null) return <Redirect to="/login" />

        if (page === 'LogoutPage') {
            unsetUser()
            return <Redirect to="/login" />
        }

        switch (page) {
            case 'MenuPage': return <MenuPage activities={activities} />

            default:
        }
    }

    return (
        <BrowserRouter>
            <AppNavbar />
            <Switch>
                <Route exact path='/register' component={ RegisterPage } />
                <Route exact path='/login' component={ LoginPage } />
                <Route exact path='/' render={ (props) => Load(props, 'MenuPage') } />
            </Switch>
        </BrowserRouter>
  )
}

最佳答案

当您使用 setState 时,您会看到无限渲染。位于组件内部。

setActivity(activities.map( (activity) => <ActivityItem activity={activity} />))

当它遇到它时,它会重新渲染组件,此时它将在下一次渲染时再次进入上述状态。

只需将其删除,因为您已经可以访问 activities在组件的上下文中,然后从组件返回。

return activities.map( (activity) => <ActivityItem activity={activity} />)

裸 useStates 总是导致无限渲染

此外,将数据源移动到尽可能靠近 App.js 总是有意义的。页面并没有真正使用它,而是将其传递给子组件。

您可以移动 useEffectMenuPage修复 return 语句后,它应该按预期工作。

MenuPage.js

const MenuPage = ({activities}) => {
    const [activities, setActivities] = useState([])

    // This only causes a re render once when the component is mounted
    // as the dependency list is empty
    useEffect( () => {
        GQLClient({})
           .request(Query.getActivities, null)
           .then( ({getActivities}) => {
              setActivities({getActivities});
         })
    }, [])

    console.log(activities)

    return (
       activities.map( (activity) => <ActivityItem key={activity.id} activity={activity} />
    );
}

关于javascript - 如何在 React 中映射一个 prop,它是一个对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60660134/

相关文章:

javascript - 为新的 div 添加独特的类

javascript - 使用 stopPropagation() 处理 React 事件委托(delegate)

javascript - 使用 gatsby-source-google-spreadsheet 将表格中的链接插入 Gatsby

graphql - 登录不应该是 GraphQL 中的查询吗?

asp.net - 如何使用 Javascript 获取调用它的 UserControl 的名称?

javascript - Socket.io 在页面刷新时创建多个连接

ReactJS、react-router 和 socket.io

graphql - 在 Gatsby 上渲染 Contentful Reference (many) 数组

javascript - 4 个切换按钮互相使用 javascript,但它们都不是好的听众——续集 : stupidity strikes back

javascript - 将react-select与formik一起使用时,无法读取未定义的属性 'type'