【发布时间】:2021-01-26 18:57:35
【问题描述】:
我有一种情况,我正在填充几个 material-ui 卡组件,其中包含与登录用户相关联的账单数量、在工作上花费的总小时数等。我有一个带有 SummaryCard 子项的 Summary 组件,它将一个值作为道具然后显示它:
/** @jsxImportSource @emotion/react */
import React, { Fragment, useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import Grid from '@material-ui/core/Grid'
import { makeStyles } from '@material-ui/core/styles'
import { SectionTitle, SummaryCard } from '../../atoms'
import { css } from '@emotion/react'
const styles = makeStyles({
summaryRow: {
borderBottom: '3px solid #2c3e50',
margin: '0 auto',
padding: '0 2rem 1rem',
width: '84vw'
}
})
const Summary = () => {
const classes = styles()
let billsData = useSelector(state => state.dashboardData.billsData)
let [billsCount, setBillsCount] = useState(3)
useEffect(() => {
console.log(billsData)
console.log(billsData.data)
console.log(billsData.data.length)
setBillsCount(billsData.data.length)
},[billsData])
return (
<Fragment>
<section css={summaryCSS} >
<SectionTitle title='SUMMARY' />
<Grid classes={{ root: classes.summaryRow }} container spacing={4} >
<Grid item xs={3} >
<SummaryCard color='#4E73DF' title='NUMBER OF BILLS' type='Receipt' value={billsCount} />
</Grid>
<Grid item xs={3} >
<SummaryCard color='#f6c23e' title='HOURS BILLED' type='Hours' value={0} />
</Grid>
<Grid item xs={3} >
<SummaryCard color='#1CC88A' title='TOTAL EXPENSES' type='Dollar' value={0} />
</Grid>
<Grid item xs={3} >
<SummaryCard color='#E74A3B' title='CUSTOMERS SERVED' type='Customers' value={0} />
</Grid>
</Grid>
</section>
</Fragment>
)
}
export default Summary
我已将 Redux 存储数据设置为等于 billsData(通过 useSelector),其想法是在 billsData 更新时利用 useEffect 挂钩设置 billsCount 的状态。但是,setBillsCount(billsData.data.length) 行将计数设置为 0,即使我已经在控制台中记录了该数组不为空的证明:
更糟糕的是,setBillsCount 正在覆盖我的初始 billsCount 值,我已将其设置为 3 以证明 useEffect 实际上按预期触发,但未设置正确的值。然后 SummaryCard 组件使用新的 0 值重新渲染,如下所示:
最后,这是 React 组件的屏幕截图,显示选择器已填充但状态仍为 0,并且 Redux 存储已填充,正如预期的那样:
那么为什么 setBillsCount 会将我的 billsCount 覆盖为 0?此外,如果我在编辑器中进行更改并重新保存以更新我的 localhost 实例,则会加载正确的值 (18),如下所示:
我已经尝试了几件事,包括:1)添加一个 initialRender 状态和依赖项,这样 useEffect 会在 initalRender 等于 0 时递增以触发重新渲染,2)创建一个新数组,将 billsData.data 数组推入它,并尝试使用 newArray.length 设置 billsCount,3)实现一个临时计数变量并在数组上运行 .forEach 循环以在使用它设置状态之前增加计数,以及 4)将 billsData 传递给 Summary 组件作为来自父组件的 {props}。
更新:在检查了我的 Redux 操作/reducers 之后,我觉得我好像在遵循推荐的结构,但我不确定:
export const addUser = user => ({
type: 'ADD_USER',
payload: user
})
export const addActivityData = data => ({
type: 'ADD_ACTIVITY_DATA',
payload: data
})
export const addBillsData = data => ({
type: 'ADD_BILLS_DATA',
payload: data
})
export const addCustomerData = data => ({
type: 'ADD_CUSTOMER_DATA',
payload: data
})
export const addJobsData = data => ({
type: 'ADD_JOBS_DATA',
payload: data
})
export const addWorkerData = data => ({
type: 'ADD_WORKER_DATA',
payload: data
})
dataReducer.js
const initialState = {}
export default function dataReducer (state = initialState, action) {
switch (action.type) {
case 'ADD_ACTIVITY_DATA': {
return Object.assign({}, state, {
activityData: action.payload
})
}
case 'ADD_BILLS_DATA': {
return Object.assign({}, state, {
billsData: action.payload
})
}
case 'ADD_CUSTOMER_DATA': {
return Object.assign({}, state, {
customerData: action.payload
})
}
case 'ADD_JOBS_DATA': {
return Object.assign({}, state, {
jobsData: action.payload
})
}
case 'ADD_WORKER_DATA': {
return Object.assign({}, state, {
workerData: action.payload
})
}
default:
return state
}
}
【问题讨论】:
-
也许你在reducer中改变
state.dashboardData.billsData?我看不到您如何有 2 个日志显示 18 的数组,然后将长度记录为 0。也许尝试记录:console.log('data at this moment:',JSON.stringify(billsData.data,undefined,2)) -
我不知道为什么会发生这种情况,但我也不明白为什么您将计数保存到状态而不是直接使用计数?
<SummaryCard color='#4E73DF' title='NUMBER OF BILLS' type='Receipt' value={billsData.data.length} /> -
@LindaPaiste 是我的错,我忘了说我也已经尝试过了,结果相同。我之所以选择使用 useState/useEffect 设置状态的原因是,当这种方法失败时,我认为我必须调用 useEffect 来更改子道具并重新渲染组件。
-
@HMR 这是个好主意,谢谢,我会看看我是否正在改变数据。至于你的第二个建议,我试过了,结果一样:
data at this moment: []. -
@ChardBrez 这不是相同的结果,但是在您发布的图像中它显示
Array(18);当您尝试将其记录为字符串时,您会得到一个空数组,当记录长度时,您会得到 0。这意味着在某些时候您会在该日志之后对其进行变异。
标签: javascript reactjs react-redux