繁体   English   中英

我在控制台中收到此错误:无法读取未定义的属性“ some”

[英]I am getting this error in the console : Cannot read property 'some' of undefined

TypeError:无法读取未定义的``属性''我不知道为什么ı在我检查下面所有代码的时候都会出现此错误:(试图了解反应的方式:)那么这的目的是什么我在contextprovider上包装的属性,例如联系人加载和我需要的功能

import React, { useState, useContext } from 'react'
import ContactContext from '../context/contactContext'

export default function ContactForm() {
  const name = useFormInput('')
  const email = useFormInput('')

  const contactContext = useContext(ContactContext)
  const { addContact } = contactContext

  const onSubmit = () => {
    addContact(name.value, email.value)
    name.onReset()
    email.onReset()
  }
  return (
   SOME HTML CODE HERE
  )
}

//contactState.js
import React, { useReducer } from 'react'
import _ from 'lodash'
import ContactContext from './contactContext'
import ContactReducer from './contactReducer'

const ContactState = props => {
  const initialState = {
    contacts: [
      {
        id: '098',
        name: 'Diana Prince',
        email: 'diana@us.army.mil'
      }
    ],
    loading: false,
    error: null
  }

  const [state, dispatch] = useReducer(ContactReducer, initialState)
  const [contacts, loading] = state
  const addContact = (name, email) => {
    dispatch({
      type: 'ADD_CONTACT',
      payload: { id: _.uniqueId(10), name, email }
    })
  }
  const delContact = id => {
    dispatch({
      type: 'DEL_CONTACT',
      payload: id
    })
  }
  return (
    <ContactContext.Provider
      value={{
        contacts,
        loading,
        addContact,
        delContact
      }}
    >
      {props.children}
    </ContactContext.Provider>
  )
}
export default ContactState

//contactReducer.js
export default (state, action) => {
  switch (action.type) {
    case 'ADD_CONTACT':
      return {
        contacts: [...state, action.payload]
      }
    case 'DEL_CONTACT':
      return {
        contacts: state.contacts.filter(
          contact => contact.id !== action.payload
        )
      }
    case 'START':
      return {
        loading: true
      }
    case 'COMPLETE':
      return {
        loading: false
      }
    default:
      throw new Error()
  }
}

//contactContext.js
import { createContext } from 'react'
const contactContext = createContext()
export default contactContext

在减速器中,添加联系人时,您散布了错误的状态键。 这应该解决它:

case 'ADD_CONTACT':
  return {
    contacts: [...state.contacts, action.payload]
  }

我看不到您在应用程序中使用ContactState的位置。 如果您不使用它并使用它呈现ContactForm组件,那么您将无法获得任何上下文值。 您应该将其呈现为:

<ContactState>
  <ContactForm />
</ContactState>

在您应用的合适位置。 另外,您无法像这样获得contactsloading

const [ contacts, loading ] = state;

state不是数组,而是这里的对象。 您应该使用:

const { contacts, loading } = state

您可以在下面找到代码的简化版本。 我删除/更改了一些零件以便尽可能地运行它。 您应该像@Asaf David在他们的答案中提到的那样来修复减速器,但这不是这里的主要问题。 解决上下文问题后,您可以尝试修复减速器。

关于您的问题,如果您通过查看本示例来了解React的工作方式,那么您很容易感到困惑。 因为Context是一个高级概念(至少对于初学者而言)。 此外,代码将useReducerContext useReducer使用,这使事情变得更加复杂。 如果您打算了解React本身,那么请从入门指南开始。

通过使用上下文,我们可以将数据自上而下传递到最深层的组件。 但是,为了使用该数据,应将那些组件呈现为上下文提供者的子级。

在您的代码中,您正在ContactState中执行此操作,但从未使用过它。 另外,在该组件中,您正在使用useReducer定义状态,并通过value将状态提供给上下文。

最后,在ContactForm组件中,您正在使用useContext挂钩来获取上下文数据。 在当前代码中,由于未在提供程序中呈现此组件,因此contactContext是未定义的,并且会出现错误。 您无法通过未定义获取addContact

在我的示例中,我正在检索contacts以显示某些内容。 同样,我已经从您的代码中更改/删除了某些部分。

 const { createContext, useContext, useReducer } = React; const ContactContext = createContext(); function ContactForm() { // Changed those values const name = ""; const email = ""; const contactContext = useContext(ContactContext); // changed addContact -> contacts const { contacts } = contactContext; const onSubmit = () => { addContact(name.value, email.value); name.onReset(); email.onReset(); }; // added some data to render return <div>{contacts[0].name}</div>; } function ContactReducer(state, action) { switch (action.type) { case "ADD_CONTACT": return { contacts: [...state, action.payload] }; case "DEL_CONTACT": return { contacts: state.contacts.filter( contact => contact.id !== action.payload ) }; case "START": return { loading: true }; case "COMPLETE": return { loading: false }; default: throw new Error(); } } const ContactState = props => { const initialState = { contacts: [ { id: "098", name: "Diana Prince", email: "diana@us.army.mil" } ], loading: false, error: null }; const [state, dispatch] = useReducer(ContactReducer, initialState); const { contacts, loading } = state; const addContact = (name, email) => { dispatch({ type: "ADD_CONTACT", // removed lodash part, added a static id payload: { id: 1, name, email } }); }; const delContact = id => { dispatch({ type: "DEL_CONTACT", payload: id }); }; return ( <ContactContext.Provider value={{ contacts, loading, addContact, delContact }} > {props.children} </ContactContext.Provider> ); }; // added the relevant render part ReactDOM.render( <ContactState> <ContactForm /> </ContactState>, document.getElementById("root") ); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root" /> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM