Почему мой компонент не перерисовывается после отправки формы и установки состояния с помощью Firebase? - PullRequest
0 голосов
/ 16 мая 2019

Я создаю компонент, который должен повторно отображаться после отправки формы, и он отлично отправляет базу данных, но я хочу, чтобы компонент повторно отображался после отправки и не обновлял страницу.

Я слышал, что React рендерится после изменения состояния, и я попытался установить состояние входных данных формы при отправке.

import React, { Component } from 'react';
import { withFirebase } from '../Firebase';
import { FirebaseContext } from '../Firebase';
import { Link } from 'react-router-dom';
import AddNew from '../AddNew';
import { compose } from 'recompose';
import Firebase from '../Firebase';
import * as ROUTES from '../../constants/routes';
import { throwStatement, thisExpression, tsExpressionWithTypeArguments } from '@babel/types';



class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      loading: false,
      isHidden: false,
      name: '',
      image: '',
      data: []
    }

    this.baseState = this.state

    this.toggleAddNew = this.toggleAddNew.bind(this);
  }

  getPosts() {
    this.props.firebase.getClients().then(snapshot => {
      this.setState({
        data: snapshot.docs
      })
    });
  }

  // Component lifecycle methods

  componentWillMount() {
    this.getPosts()
  }

  componentDidUpdate(){
    console.log('updated')
  }

  toggleAddNew() {
    this.setState({
      isHidden: !this.state.isHidden
    })
  }

  updateInput = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

  resetForm = () => {
    this.setState(this.baseState)
  }

  deletePost = (id) => {
    this.props.firebase.deleteClient(id);
  }

  addClient = e => {
    e.preventDefault();

    this.props.firebase.addClient().add({
      name: this.state.name,
      image: this.state.image
    })
    this.setState({
      name: '',
      image: ''
    });
    this.resetForm();
  };


  render() {

    const renderPosts = this.state.data.map((item) => (

      <li data-id={item.id} className="client-wrapper col-sm-4">
        <button onClick={() => this.deletePost(item.id)}>X</button>
        <Link to={`/dates/${item.id}`}>
          <h2>{item.data().name}</h2>
        </Link>
        <Link to={`/dates/${item.id}`}>
          <img src={item.data().image} />
        </Link>
      </li>

    ));

    return (
      <div>
        <ul id="client-list" className="row">{renderPosts}</ul>
        <button onClick={this.toggleAddNew.bind(this)}>Add New</button>
        {this.state.isHidden ? 
        <div id="add-new-form-wrapper">
          <button onClick={this.toggleAddNew.bind(this)} id="x-add-new">X</button>
          <form onSubmit={this.addClient.bind(this)} id="add-new-form">
            <input type="text" name="name" placeholder="Name" onChange={this.updateInput} value={this.state.name} />
            <input type="text" name="image" placeholder="Image" onChange={this.updateInput} value={this.state.image} />
            <button type="submit">Submit</button>
          </form>
        </div> :
          ''}
      </div>
    )
  }

}

export default compose(
  withFirebase,
)(Home);

1 Ответ

0 голосов
/ 17 мая 2019

Это

this.baseState = this.state

делает только копию ссылки на объект, а не копию объекта состояния (со значениями свойств).

Когда у нас есть справочная копия

resetForm = () => { this.setState(this.baseState) }

может работать как state = state, ничего не делает.

Копирование объекта (с текущими значениями свойств) может быть сделано (например,) следующим образом:

this.baseState = {...this.state}

С этим небольшим исправлением он должен работать ...

... если нет, попробуйте

resetForm = () => {
  this.setState({...this.baseState})
}

Вы также можете обновить поле состояния, указав текущее время, чтобы вызвать повторную визуализацию, или просто позвонить this.forceUpdate() (см. docs ).

Кстати - resetForm не должен перезаписывать data. К счастью, у нас есть копия data ссылки на объект в baseState;)

...