Как использовать соответствующие реквизиты в react js при использовании контекстного api

#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 . Можете ли вы проверить это?