Home > Net >  Facing some errors while implementing a class component method to functional component method in a r
Facing some errors while implementing a class component method to functional component method in a r

Time:06-07

RestaurantList.js

import React, { Component } from "react";
import { Table } from 'react-bootstrap';
import { Link } from 'react-router-dom'
export default class RestaurantList extends Component {
constructor() {
super();
this.state = {
  list: null,
};
}

componentDidMount() {
fetch("http://localhost:3000/restaurant").then((response) => {
  response.json().then((result) => {
    this.setState({ list: result });
  });
});
}
render() {
return (
  <div>
    <h1>List</h1>
    {
      this.state.list ?
        <div>
          <Table striped bordered hover>
            <thead>
              <tr>
                <th>#</th>
                <th>Name</th>
                <th>Email</th>
                <th>Rating</th>
                <th>City</th>
                <th>Operation</th>
              </tr>
            </thead>
            <tbody>
              {
                this.state.list.map((item, i) =>
                  <tr>
                    <td>{item.id}</td>
                    <td>{item.name}</td>
                    <td>{item.email}</td>
                    <td>{item.rating}</td>
                    <td>{item.address}</td>
                    <td><Link to={"/update/"   item.id} style={{ color: 'blue', textDecoration: 'inherit' }}>Edit</Link></td>
                  </tr>)
              }
            </tbody>
          </Table>
        </div>
        :
        <p>Please Wait...</p>
    }
  </div>
);
}
}

RestaurantUpdate.js

In Class Component Method (It is correct)

import React, { Component } from 'react';
import NavBarManu from './NavBarManu'

class RestaurantUpdate extends Component {
constructor()
{
    super();
    this.state = {
    name: null,
    email: null,
    address: null,
    rating: null,
    id:null,
   }
}
componentDidMount()
{ 
   fetch('http://localhost:3000/restaurant/' this.props.match.params.id).then((response) => {
        response.json().then((result) => {
            console.warn(result)
             this.setState({ 
                 name:result.name,
                 email:result.email,
                 id:result.id,
                 rating:result.rating,
                 address:result.address

              })
        })
    })
}
update()
{
    fetch('http://localhost:3000/restaurant/' this.state.id, {
        method: "PUT",
        headers:{
            'Content-Type':'application/json'
        },
        body: JSON.stringify(this.state)
    }).then((result)=>{
        result.json().then((resp)=>{
            alert("Restaurant has heen Update")
        })
    })
}
render() {
    
    return (
        <div>
            <NavBarManu />
            <h1>Restaurant Update</h1>
            <div>
                <input onChange={(event) => { this.setState({ name: event.target.value }) }}
                    placeholder="Restaurant Name" value={this.state.name} /> <br /><br />
                <input onChange={(event) => { this.setState({ email: event.target.value }) }}
                    placeholder="Restaurant Email" value={this.state.email} /> <br /><br />
                <input onChange={(event) => { this.setState({ rating: event.target.value }) }}
                    placeholder="Restaurant Rating"  value={this.state.rating}/> <br /><br />
                <input onChange={(event) => { this.setState({ address:    event.target.value }) }}
                       placeholder="Restaurant Address"  value={this.state.address}/> <br       /><br />
                   <button onClick={() => { this.update() }}>Update Restaurant</button>
               </div>
           </div>
       );
   }
}

export default RestaurantUpdate;

In Functional Component(Facing some errors)

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

const RestaurantUpdate = () => {
const [name, setName] = useState(null);
const [email, setEmail] = useState(null);
const [address, setAddress] = useState(null);
const [rating, setRating] = useState(null);
const [id, setId] = useState(null);



//Want to use it like CompoundDidMount
useEffect(() => {
    fetch('http://localhost:3000/restaurant' /  id).then((response) => {
        response.json().then((result) => {
            console.warn(result)
            setName(result.name);
            setEmail(result.email);
            setId(result.id);
            setAddress(result.address);
            setRating(result.rating);
        })
    })
}, []);
//Want to display all the states in the console with their respective values. But i am unable to do it.
useEffect(() => {
    console.warn(name);
}, [id]);
return (
    <div>
        <h1>Update</h1>
        <div>
            <input onChange={(event) => { this.setState({ name: event.target.value }) }}
                placeholder="Restaurant Name" /> <br /><br />
            <input onChange={(event) => { this.setState({ email: event.target.value }) }}
                placeholder="Restaurant Email" /> <br /><br />
            <input onChange={(event) => { this.setState({ rating: event.target.value }) }}
                placeholder="Restaurant Rating" /> <br /><br />
            <input onChange={(event) => { this.setState({ address: event.target.value }) }}
                placeholder="Restaurant Address" /> <br /><br />
            <button onClick={() => { this.update() }}>Update Restaurant</button>
        </div>
    </div>
);
};

export default RestaurantUpdate;

I was expecting display of all the state in the console with the their respective data. But it is showing null values. I am facing some errors in implementing componentDidMount() in function component using hooks and in setState(). Basically I just want to use given Class Component RestaurantUpdate.js in functional component way. Definitely there are some syntax errors and i am facing some difficulties in implementing them. So please point out the error and provide me the right solution.

Blockquote

CodePudding user response:

Add a conditional render and see if it works.

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

const RestaurantUpdate = () => {
    const [name, setName] = useState(null);
    const [email, setEmail] = useState(null);
    const [address, setAddress] = useState(null);
    const [rating, setRating] = useState(null);
    const [id, setId] = useState(null);
    const [result, setResult] = useState(null);



    //Want to use it like CompoundDidMount
    useEffect(() => {
        fetch('http://localhost:3000/restaurant' /  id).then((response) => {
            response.json().then((result) => {
                console.warn(result)
                setResult(result);
                setName(result.name);
                setEmail(result.email);
                setId(result.id);
                setAddress(result.address);
                setRating(result.rating);
            })
        })
    }, []);
    //Want to display all the states in the console with their respective values. But i am unable to do it.
    useEffect(() => {
        console.warn(name);
    }, [id]);
    return (
        <>
            {
                result ? (
                    <div>
                        <h1>Update</h1>
                        <div>
                            <input onChange={(event) => { setName(event.target.value) }} value={name}
                                placeholder="Restaurant Name" /> <br /><br />
                            <input onChange={(event) => { setEmail(event.target.value) }} value={email}
                                placeholder="Restaurant Email" /> <br /><br />
                            <input onChange={(event) => { setRating(event.target.value) }} value={rating}
                                placeholder="Restaurant Rating" /> <br /><br />
                            <input onChange={(event) => { setAddress(event.target.value) }} value={address}
                                placeholder="Restaurant Address" /> <br /><br />
                            <button onClick={() => { update() }}>Update Restaurant</button>
                        </div>
                    </div>
                ) : (<div>loading</div>)
            }
        </>


    );
};

export default RestaurantUpdate;

CodePudding user response:

There are a few things to address here that probably will help you to achieve the desired result.

First is the id, probably it should come from the a call to useParams right? if so, no need to declare it as a state.

const { id } = useParams();

Then, in the useEffect even though you want to simulate compoundDidMount the recommended solution is to include in the deps array all the values used internally in the useEffect. this link hooks docs is super helpful.

Next, you probably is having some warnings in the console complaining about "value" prop on "input" should not be null and A component is changing an uncontrolled input to be controlled, this can be avoided just by setting an initial state for the inputs different of null or undefined, and this could be:

  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [address, setAddress] = useState("");
  const [rating, setRating] = useState(0);

or also by using the technique displayed in the previous answers will help you to remove from these warnings.

Also in your example the value field was missing in the inputs

<input 
   onChange={(event) => setName(event.target.value)} 
   placeholder="Restaurant Name" 
   value={name} /> 

And I guess with these tweaks you should be fine. I've put together a sandbox that might help you to unfold everything. example

  • Related