【问题标题】:TypeError: Invalid attempt to spread non-iterable instance with use effectTypeError:无效尝试传播具有使用效果的不可迭代实例
【发布时间】:2020-12-16 00:19:25
【问题描述】:

不知道为什么,但我收到以下错误消息:

TypeError: Invalid attempt to spread non-iterable instance

有没有办法在触发useEffect 之前映射数据以便能够存储在useEffect 中?

看起来这张地图似乎不起作用。

  const projectId = scheduleData && scheduleData.map(item => item.project_id).map(x => ({label: x, value: x}))
const schedules = () => {


  const loading = useContext(LoadingContext)
  const snackbar = useContext(SnackbarContext)
  const user = useContext(UserContext)


  const [scheduleData ,setScheduleData] = useState(null)
  const [usageMode, setUsageMode] = useState(false)

  const [scheduleFieldData, setScheduleFieldData] = useState({})

  const [projectsAutoComplete, setProjectsAutoComplete] = useState([])
  const [domainsAutoComplete, setDomainsAutoComplete] = useState([])

  console.log(projectId, 'projectId');

  console.log(projectsAutoComplete)

  const projectId = scheduleData && scheduleData.map(item => item.project_id).map(x => ({label: x, value: x}))

useEffect(() => {
  setProjectsAutoComplete([...projectId])
}, [])
  console.log(projectsAutoComplete);

  useEffect(() => {
    async function onLoadScheduleData(){
      loading.setLoading(true)
      const results = await get('get_testing_schedules', user.user)
      setScheduleData(results.data)
      loading.setLoading(false)
    }
    onLoadScheduleData()
  },[])

  const onClick = () => {
    setUsageMode(!usageMode)
  }

  console.log(usageMode);

  const onScheduleFieldUpdate = (e, valueFromAutoComplete, nameFromAutoComplete) => {

    const name = nameFromAutoComplete ? nameFromAutoComplete
    : e.target.name || e.target.getAttribute('name')
    const value = valueFromAutoComplete ? valueFromAutoComplete.map(val => val.value).join(',')
      : e.target.innerText ? e.target.innerText
      : e.target.value

      setScheduleFieldData({...scheduleFieldData, ...{[name]: value}})
  }

  const onDomainAutoCompleteFieldUpdate = (e) => {
    const value = e.target.innerText.toLowerCase()
    const projectIdFiltered = projectId.filter(id => id.label.toLowerCase().startsWith(value))
    setProjectsAutoComplete(projectIdFiltered)
  }
  console.log(scheduleFieldData);

  return (
    <div className=' CriticalObjectsGrid'>
 
       <React.Fragment>
          {configs.map((config, k) => {
            const Field = config.field
            return (
              <div key={k} className='Main' style={{textAlign: 'center'}} >
                <Field  
                  uniqueIdentifier={k} 
                  name={config.name} 
                  onChange={onScheduleFieldUpdate}
                  onSelect={onScheduleFieldUpdate}
                  onAutoCompleteOnChange={onDomainAutoCompleteFieldUpdate}
                  value={scheduleFieldData[config.name]}
                  initialValues={
                  scheduleFieldData[config.name]}
                  options={projectsAutoComplete}
                />
              </div>
            )
          })}
        </React.Fragment>
      }
    </div>
  )
}

export default schedules

更新代码

const schedules = () => {


  const loading = useContext(LoadingContext)
  const snackbar = useContext(SnackbarContext)
  const user = useContext(UserContext)
  const autoComplete = useContext(AutoCompleteContext)



  const [scheduleData ,setScheduleData] = useState(null)
  const [usageMode, setUsageMode] = useState(false)

  const [scheduleFieldData, setScheduleFieldData] = useState({})

  const [projectsAutoComplete, setProjectsAutoComplete] = useState([])




  // const projectId = scheduleData && scheduleData.map(item => item.project_id).map(x => ({label: x, value: x}))



  const [ScheduleAutoComplete, setScheduleAutoComplete] = useState([])


  const intervals = ['"Daily"', '"Weekly"']

  const projectId = scheduleData && scheduleData.map(item => item.project_id).map(x => ({label: x, value: x}))

useEffect(() => {
  // setProjectsAutoComplete([...projectId])

  setScheduleAutoComplete([...intervals])




}, [])

console.log(projectsAutoComplete);




  useEffect(() => {
    async function onLoadScheduleData(){
      loading.setLoading(true)
      const results = await get('get_testing_schedules', user.user)
      setScheduleData(results.data)

      if (projectId){setProjectsAutoComplete([...projectId])
      }
      loading.setLoading(false)
    }
    onLoadScheduleData()
  },[])

  const onClick = () => {
    setUsageMode(!usageMode)
  }

  console.log(projectsAutoComplete);



  const onScheduleFieldUpdate = (e, valueFromAutoComplete, nameFromAutoComplete) => {

    const name = nameFromAutoComplete ? nameFromAutoComplete
    : e.target.name || e.target.getAttribute('name')
    const value = valueFromAutoComplete ? valueFromAutoComplete.map(val => val.value).join(',')
      : e.target.innerText ? e.target.innerText
      : e.target.value

      setScheduleFieldData({...scheduleFieldData, ...{[name]: value}})


  }

  const onDomainAutoCompleteFieldUpdate = () => { 
    setScheduleAutoComplete(intervals)
    setProjectsAutoComplete(projectId)



  }

  console.log(projectsAutoComplete);



  return (
    <div className=' CriticalObjectsGrid'>
      {usageMode === false ? 
        <React.Fragment>
          <Button
          text='Creat schedule'
          onClick={onClick}
          />
        </React.Fragment>

        :

        <React.Fragment>
          {configs.map((config, k) => {
            const Field = config.field
            return (
              <div key={k} className='Main' style={{textAlign: 'center'}} >
                <Field  
                  uniqueIdentifier={k} 
                  name={config.name} 
                  onChange={onScheduleFieldUpdate}
                  onSelect={onScheduleFieldUpdate}
                  onAutoCompleteOnChange={onDomainAutoCompleteFieldUpdate}
                  value={scheduleFieldData[config.name]}
                  initialValues={scheduleFieldData[config.name]}
                  options={config.name === 'interval' ? ScheduleAutoComplete : config.name === 'project' ? ['projectsAutoComplete'] : []  }

                />
              </div>
            )
          })}


        </React.Fragment>
      }


    </div>
  )
}

export default schedules

【问题讨论】:

  • 你能打印出 scheduleData 吗? [...projectId]: projectId 似乎不是一个数组(不可迭代)
  • 是的,它返回给我一个数组 [70,71] 我已经在我的代码中更新了
  • 好像打到使用效果的时候不想捡起来了
  • 试试const projectId = scheduleData ? scheduleData.map(item =&gt; item.project_id).map(x =&gt; ({label: x, value: x})) : [] 即使没有scheduleData也需要一直是数组
  • 嘿,谢谢,但是当我记录 projectsAutocomplete 它返回一个空数组。

标签: reactjs use-effect


【解决方案1】:

此错误是指您尝试在第一个 useEffect 挂钩中传播 projectId。在执行时,projectId 的值为 null,因为它从以下行中获取其值,其中 scheduleData 的初始值为 null。

const projectId = scheduleData && scheduleData.map(item => item.project_id).map(x => ({label: x, value: x}))

为避免此错误,您可以简单地将 setProjectsAutoComplete([...projectId]) 包装在 if (projectId) 检查中,如下所示:

useEffect(() => {
   if (projectId){
      setProjectsAutoComplete([...projectId])
   }
}, [])

但更好的解决方案是将您的两个 useEffect 钩子组合起来,以便 setProjectsAutoComplete([...projectId])onLoadScheduleData() 之后运行

编辑:

试试这个:

    const [projectId, setProjectId] = useState([])

    const intervals = ['"Daily"', '"Weekly"']

    async function onLoadScheduleData(){
        loading.setLoading(true)
        const results = await get('get_testing_schedules', user.user)
        if (results.data) {
            id = results.data.map(item => item.project_id).map(x => ({label: x, value: x}))
            setProjectId(id)
            setProjectsAutoComplete([...id])
        }
        loading.setLoading(false)
    }

    useEffect(() => {
        setScheduleAutoComplete([...intervals])
        onLoadScheduleData()
    },[])

    const onClick = () => {
        setUsageMode(!usageMode)
    }

我已经完全删除了 scheduleData 变量,因为它看起来不需要保持在状态。相反,我将projectId 设为有状态变量,因为它似乎确实在其他地方使用过。我将onScheduleLoadData 函数定义移到useEffect 挂钩之外,并将projectId 逻辑移到其中。我还结合了两个 useEffect 钩子,因为它们具有相同的依赖项。如果这更符合您的要求,请告诉我。

【讨论】:

  • 谢谢,但我得到一个空数组,有什么想法吗?我会更新代码
  • 我将用一些新代码为您编辑我的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2019-06-25
  • 2020-08-10
  • 2021-01-14
  • 2019-07-18
  • 2021-10-10
  • 1970-01-01
相关资源
最近更新 更多