React Doesn't re-render after state change?

React Doesn't re-render after state change?
0.0 0

#1

if does React re-render a component after every State change, why isn’t it working with this code once I submit the newUser in handleFormSubmit() ? I see it being updated on the react console, but I only see it in the DOM once I actually reload the page, anything I missed here??

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

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [],
      newUser: {
        name: '',
        email: '',
        country: '',
        img: ''
      }
    };

    this.handleFormSubmit = this.handleFormSubmit.bind(this);
    this.handleInput = this.handleInput.bind(this);
  }

  fetchData() {
    fetch('http://127.0.0.1:3000/')
      .then((res) => {
        return res.json();
      })

      .then(users =>
        this.setState({
          users: users
        }))
      // handle the error
      .catch(err => console.log(err));
  }

  componentDidMount() {
    this.fetchData();
  }

  // this changes all the inputs
  handleInput(e) {
    const { value } = e.target;
    const { name } = e.target;
    this.setState(
      prevState => ({
        newUser: {
          ...prevState.newUser,
          [name]: value
        }
      }),
      () => console.log(this.state.newUser)
    );
  }

  handleFormSubmit(e) {
    e.preventDefault();
    const userData = this.state.newUser;
    this.setState({
      users: [...this.state.users, userData]
    });

    fetch('http://127.0.0.1:3000/register', {
      method: 'POST',
      body: JSON.stringify(userData),
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      }
    }).then((response) => {
      response.json().then((data) => {
        console.log('Successful' + data);
      });
    });
  }

  render() {
    const { users } = this.state;
    const style = {
      display: 'flex',
      flexWrap: 'wrap'
    };

    const styleForm = {
      width: '100%',
      height: '150px'
    };

    const input = {
      width: '300px',
      display: 'flex',
      flexDirection: 'row',
      height: '20px'
    };
    // const users = 0;
    return (
      <div style={style}>
        {/* <SingUp /> */}

        <div style={styleForm}>
          <h1>Sign Up!</h1>
          <form onSubmit={this.handleFormSubmit}>
            <input
                type="text" placeholder="name" name="name"
                value={this.state.newUser.name} handleChange={this.handleInput} onChange={this.handleInput}
            />

            <input
              type="text" placeholder="email" name="email"
                value={this.state.newUser.email} handleChange={this.handleInput} onChange={this.handleInput}
            />

            <input
              type="text"
              placeholder="country"
              name="country"
              value={this.state.newUser.country}
              handleChange={this.handleInput}
              onChange={this.handleInput}
            />

            <input
                type="text" placeholder="img url" name="img"
                value={this.state.newUser.img} handleChange={this.handleInput} onChange={this.handleInput}
            />

            <button onSubmit={this.handleFormSubmit}>OK</button>
          </form>
        </div>

        <div style={style} />
        {users.length > 0 ? (
          users.map((user) => {
            return (
              <div>
                <User
                    key={user.email} email={user.email} fullName={user.full_name}
                    country={user.country} img={user.img} created={user.created_at}
                />
              </div>
            );
          })
        ) : (
          <p> no users found</p>
        )}
      </div>
    );
  }
}

const User = (props) => {
  const style = {
    border: '1px solid black',
    width: '200px',
    // height: '220px',
    backgroundColor: '#bbd',
    textAlign: 'Center'
  };

  return (
    <div style={style}>
      {/* <p>{props.email}</p> */}
      <h4>{props.fullName}</h4>
      <p>{props.country}</p>
      <p>{props.created}</p>
      <img src={props.img} alt="" />
    </div>
  );
};

export default App;


#2

I copy and pasted your code, disabled your fetch() API call in handleFormSubmit(), and a box with purple background and the country would pop up—is this that you are referring to? I haven’t tried futher to see if fetch is doing anything funny but a casual look suggests that it’s not.

You do have a other problems though—in fact, if you are referring to names and such not showing up, instead of nothing showing up at all as your post seems to suggest, I think the problem is because a user object seems to have a different property names for name—in your render method it’s user.full_name but the each of the user object, if I’m not mistaken, has only user.name.

There are also other errors in the console that you may want to fix, too.

I hope that helps!


#3

That was it! I was passing user.name on my component and on my API I was doing

  const user = {
    email: req.body.email,
    full_name: req.body.name,
    country: req.body.country,
    img: req.body.img
  };

so it would only show when it fetched the data again.