#javascript #reactjs #react-hooks #fetch #context-api
#javascript #reactjs #реагирующие хуки #выборка #реагировать-контекст
Вопрос:
Я создаю базовое приложение и использую контекстный api, выборку, реагирующие хуки для всех компонентов, кроме компонента контекстного api, потому что я все еще учусь использовать хуки.
Я извлек свои данные из серверной части, я хочу использовать один компонент для создания и обновления своих данных, моя основная проблема в том, что я не знаю, как использовать реквизит соответствия внутри поставщика contextApi, чтобы получить идентификатор для editform и singleItem с помощью параметров. Я создал функцию, которая вызывает singleItem, и я передал ее в свой компонент формы, чтобы она могла быть начальным значением в случае редактирования, но это не сработало. Я получил сообщение об ошибке Unhandled Rejection (TypeError): Cannot read property 'params' of undefined
.
мой компонент контекстного api
import React, { Component, createContext } from 'react'
export const ContactContext = createContext()
export class ContactContextProvider extends Component {
state = {
Contact : [],
singleContact:{}
}
componentDidMount(){
fetch('http://127.0.0.1:5000/Contact')
.then(res=>res.json())
.then(data=>{
this.setState({
Contact:data
})
})
this.getSingleItem()
}
getSingleItem = async() => {
const fetch_id = await fetch(`http://127.0.0.1:5000/Contact/${this.props.match.params.id}`)
const data = await fetch_id.json()
this.setState({singleContact:data})
}
createContact = (item) =>{
const req = {
method : 'POST',
headers : {'Content-Type':'application/json'},
body: JSON.stringify(item)
}
fetch('http://127.0.0.1:5000/Contact/add', req)
.then(res=>res.json())
.then(data=> data)
}
editContact = (item) => {
const req = {
method : 'POST',
headers : {'Content-Type' : 'application/json'},
body : JSON.stringify(item)
}
fetch(`http://127.0.0.1:5000/Contact/edit/${this.props.match.params.id}`)
.then(res=>res.json())
.then(data=>console.log(data))
}
deleteContact = (_id) => {
fetch(`http://127.0.0.1:5000/Contact/${_id}`, {method:'DELETE'})
.then(res=>res.json())
.then(data=>console.log(data))
this.setState({
Contact : [...this.state.Contact.filter(item => item._id !== _id)]
})
}
render() {
return (
<ContactContext.Provider value={{...this.state, createContact:this.createContact, editContact:this.editContact, deleteContact:this.deleteContact}}>
{this.props.children}
</ContactContext.Provider>
)
}
}
export default ContactContextProvider
Это моя форма для создания и редактирования данных
import { Form, Button, Col} from 'react-bootstrap';
import React, {useState, useContext} from 'react'
import { ContactContext } from '../context/ContactContext';
function Contactform() {
const {createContact, singleContact, editContact} = useContext(ContactContext)
const [Contact, setContact] = useState({
firstName: singleContact.firstName || '',
lastName: singleContact.lastName || '',
company: singleContact.company || '',
phone: singleContact.phone || '',
email: singleContact.email || '',
note: singleContact.note || ''
})
const handleChange = (e) =>{
setContact((prevState)=>({
...prevState,
[e.target.name]:e.target.value
}))
}
const handleSubmit = (e) =>{
e.preventDefault()
const item = {
firstName: Contact.firstName,
lastName: Contact.lastName,
company: Contact.company,
phone: Contact.phone,
email: Contact.email,
note: Contact.note
}
if(Contact===''){
createContact(item)
}
else {
editContact(item)
}
}
return (
<Form id='form' onSubmit={handleSubmit} >
<Form.Row>
<Form.Group as={Col} >
<Form.Label>First Name</Form.Label>
<Form.Control name='firstName' value={Contact.firstName} onChange={handleChange} type="text" placeholder="First Name" />
</Form.Group>
<Form.Group as={Col} >
<Form.Label>Last Name</Form.Label>
<Form.Control name='lastName' value={Contact.lastName} onChange={handleChange} type="text" placeholder="Last Name" />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col} >
<Form.Label>Company</Form.Label>
<Form.Control name='company' value={Contact.company} onChange={handleChange} type="text" placeholder="Company" />
</Form.Group>
<Form.Group as={Col} >
<Form.Label>Phone</Form.Label>
<Form.Control name='phone' value={Contact.phone} onChange={handleChange} type="text" placeholder="Phone" />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col} >
<Form.Label>Email</Form.Label>
<Form.Control name='email' type="email" value={Contact.email} placeholder=" email" onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Group >
<Form.Label>Note</Form.Label>
<Form.Control as="textarea" name='note' value={Contact.note} onChange={handleChange} rows={3} placeholder='Note'/>
</Form.Group>
<Button id='form_btn' variant="primary" type="submit">
Submit
</Button>
</Form>
)
}
export default Contactform
Комментарии:
1. Пожалуйста, предоставьте краткие примеры кода с минимальным объемом кода, необходимым для воспроизведения вашей проблемы.
2. Хорошо, пожалуйста, не могли бы вы сказать мне, какие компоненты мне нужно предоставить. Я новичок в этом и учусь.
Ответ №1:
Вы можете просто сделать это. Я предполагаю, что вы уже используете react-router
. Вы можете просто использовать withRouter
hoc. Он передаст все реквизиты маршрутизатора.
// Ваш компонент контекстного api
import React, { Component, createContext } from 'react'
import { withRouter } from "react-router";
export const ContactContext = createContext()
class ContactContextProvider extends Component {
state = {
Contact : [],
singleContact:{}
}
componentDidMount(){
fetch('http://127.0.0.1:5000/Contact')
.then(res=>res.json())
.then(data=>{
this.setState({
Contact:data
})
})
this.getSingleItem()
}
getSingleItem = async() => {
const fetch_id = await fetch(`http://127.0.0.1:5000/Contact/${this.props.match.params.id}`)
const data = await fetch_id.json()
this.setState({singleContact:data})
}
createContact = (item) =>{
const req = {
method : 'POST',
headers : {'Content-Type':'application/json'},
body: JSON.stringify(item)
}
fetch('http://127.0.0.1:5000/Contact/add', req)
.then(res=>res.json())
.then(data=> data)
}
editContact = (item) => {
const req = {
method : 'POST',
headers : {'Content-Type' : 'application/json'},
body : JSON.stringify(item)
}
fetch(`http://127.0.0.1:5000/Contact/edit/${this.props.match.params.id}`)
.then(res=>res.json())
.then(data=>console.log(data))
}
deleteContact = (_id) => {
fetch(`http://127.0.0.1:5000/Contact/${_id}`, {method:'DELETE'})
.then(res=>res.json())
.then(data=>console.log(data))
this.setState({
Contact : [...this.state.Contact.filter(item => item._id !== _id)]
})
}
render() {
return (
<ContactContext.Provider value={{...this.state, createContact:this.createContact, editContact:this.editContact, deleteContact:this.deleteContact}}>
{this.props.children}
</ContactContext.Provider>
)
}
}
export default withRouter(ContactContextProvider)
Комментарии:
1. Привет, Верма. Я благодарю за помощь, я сделал именно так, как вы просили, то есть использовал withRouter для более точного сопоставления маршрута, и я перестал получать « Необработанное отклонение (ошибка типа): не удается прочитать параметры свойства undefined. ошибка « но проблема сейчас в том, что я получаю « ContactContext.js: 31 GET 127.0.0.1:5000 / Contact / undefined 400 (неверный запрос) « и когда я console.log (this.match), они определяют путь ‘/’ иparams.id является неопределенным,
2. Проверьте, отправляете ли вы идентификатор параметров или нет?
3. Я отправляю идентификатор параметров
4. Вы сказали, что вы консоль. лог
this.match
это было быthis.props.match
. Можете ли вы проверить это?