reactjs 引发未捕获的TypeError:无法在第一次呈现中读取未定义的属性(阅读“includes”)

ui7jx7zq  于 2023-03-01  发布在  React
关注(0)|答案(1)|浏览(159)

我想Map一个对象内部的数组,看看该数组是否包含teacherId,并将其存储在一个状态中,然后Map它,以便<Section />组件可以呈现它。

const teacherId = details.id;

const [availableSection, setAvailableSection] = useState([])

useEffect(() => {
  const availSection = sections.map((section) => (
    section.teachers.includes(teacherId) ? section : null
  ))
        
  setAvailableSection(availSection);

}, [sections])

在第一次转换到"/dashboard"页面时,它返回了一个错误Uncaught TypeError: Cannot read properties of undefined (reading 'includes'),但是如果我再次刷新页面,它会显示得很好。
转到"/dashboard"页面后,我想立即显示<Section />组件。
下面是我代码:
父母:

function Dashboard() {
  const dispatch = useDispatch(getSections())

  useEffect(() => {
    dispatch(getSections());
  }, [dispatch])

  const location = useLocation()

  return (
    <>
      <h1>Hello {location.state.teachersDetail.userName}</h1>
      <h1>This is where the chart and cards are located</h1>
      <Sections details={location.state.teachersDetail} />
    </>
  )
}

export default Dashboard;

截面组件:

function Sections({ details }) {
  const sections = useSelector((state) => state.sections)

  console.log(sections);

  const teacherId = details.id;

  const [availableSection, setAvailableSection] = useState([])

  useEffect(() => {
    const availSection = sections.map((section) => (
      section.teachers.includes(teacherId) ? section : null
    ))
        
    setAvailableSection(availSection);
  }, [sections])

  return (
    !sections.length
      ? <CircularProgress />
      : (
        <Grid
          container
          direction="column"
          justifyContent="flex-start"
          alignItems="stretch"
          style={{margin:'0 auto'}}
        >
          {availableSection.map((section) => (
            section !== null
              ? (
                <Grid key={section._id} item xs={12} sm={6}>
                  <Section section={section}/>
                </Grid>
              )
              : null
          ))}
        </Grid>
      ) 
  )
}

export default Sections

下面是section对象:
章节名称:"ICT-5B",教师:(3)["1"、"2"、"3"],标识符:"63英尺493英寸77英尺87英寸1723英寸553英寸"

7eumitmz

7eumitmz1#

section.teachers是未定义的。如果你真的只想过滤sections数组,如果有一个teachers数组包含teacherId,那么我建议如下,在 * potentially undefined * section.teachers属性上使用null检查。

const sections = useSelector((state) => state.sections);

const teacherId = details.id;

const [availableSection, setAvailableSection] = useState([]);

useEffect(() => {
  const availSection = sections.filter(
    (section) => section.teachers?.includes(teacherId)
  );
    
  setAvailableSection(availSection);
}, [sections, teacherId]);

...

还要注意的是availableSection是我们认为的派生状态,它是一个通用的React反模式,用于将派生状态存储在本地React状态中。几乎任何时候,只要你有一个useState/useEffect对,你真正想要使用的就是useMemo钩子。
示例:

const sections = useSelector((state) => state.sections);

const teacherId = details.id;

const availableSection = useMemo(() => {
  return sections.filter(
    (section) => section.teachers?.includes(teacherId)
  );
}, [sections, teacherId]);

...

如果你不需要所选的sections状态 * 而不是 * 来计算availableSection值,那么你可以把逻辑移到useSelector钩子中。
示例:

const teacherId = details.id;

const availableSection = useSelector((state) => state.sections.filter(
  (section) => section.teachers?.includes(teacherId)
));

...

相关问题