![](/img/trans.png)
[英]I am getting an error Typerror Cannot read property 'execute' of undefined
[英]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>
在您应用的合适位置。 另外,您无法像这样获得contacts
和loading
:
const [ contacts, loading ] = state;
state
不是数组,而是这里的对象。 您应该使用:
const { contacts, loading } = state
您可以在下面找到代码的简化版本。 我删除/更改了一些零件以便尽可能地运行它。 您应该像@Asaf David在他们的答案中提到的那样来修复减速器,但这不是这里的主要问题。 解决上下文问题后,您可以尝试修复减速器。
关于您的问题,如果您通过查看本示例来了解React的工作方式,那么您很容易感到困惑。 因为Context
是一个高级概念(至少对于初学者而言)。 此外,代码将useReducer
与Context
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.