метод onSubmit, выполняемый при рендеринге в React с Firebase - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь установить документ внутри коллекции в Firebase FireStore.

Я создал компонент, который отображает элемент div с кнопкой внутри, а затем он условно отображает FormValidation (форму) из состояния open (модуль для простой проверки формы в реакции).

Кнопка устанавливает open в значение true, если это еще не так.

Затем выполняется проверка формы, у нее есть метод onsubmit, кнопка с type="submit" и кнопка, которая устанавливает open в ложь, если она еще не ложна (поэтому проверка формы исчезает).

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

Очевидно, что он не должен запускаться, пока вы не нажмете на кнопку с type="submit"

Вот полный код:

import React from 'react'; import { ValidatorForm } from 'react-form-validator-core'; import TextInput from '../TextInput'; import { compose } from 'recompose';

import PlusIcon from '../../resources/icons/add.svg'; import PlusIconBlack from '../../resources/icons/addBlack.svg'; import ArrowIcon from '../../resources/icons/arrowDown.svg'; import BinIcon from '../../resources/icons/rubbishBin.svg';

import ButtonStyles from './button.module.css'; import ListStyles from './list.module.css'; import GameStyles from './game.module.css';

import { withAuthorization } from '../Session'; import { withFirebase } from '../Firebase';

class Games extends React.Component {   constructor(props) {
    super(props);   }

  render() {
    return(
      <div style={{marginBottom: '6em'}}>
        <h1 style={{marginTop: '2em'}}>Listas de Videojuegos</h1>
        <span style={{display: 'block', width: '100%', height: '2px', background: '#ccc', marginTop: '0.5em'}} />
        <ListsContainer />
      </div>
    );   } }

class ListsContainer extends React.Component {   constructor(props) {
    super(props);   }

  render() {
    return(
      <div style={{marginTop: '3em'}}>
        <AddButton backgroundColor="#8489C8" icon={PlusIcon} text="Añadir lista" textColor="#fff" type="list" />
        <List img="https://i.pinimg.com/originals/30/0e/58/300e58c8416a68dcfcf1761501348243.jpg" backgroundColor="#6168B8" name="Lista 1" games="5" />
        <List img="https://i.pinimg.com/originals/30/0e/58/300e58c8416a68dcfcf1761501348243.jpg" backgroundColor="#6168B8" name="Lista 2" games="26" />
        <List img="https://i.pinimg.com/originals/30/0e/58/300e58c8416a68dcfcf1761501348243.jpg" backgroundColor="#6168B8" name="Lista 1" games="5" />
      </div>
    );   } }

class List extends React.Component {   constructor(props) {
    super(props);

    this.state = {
      open: false,
    };

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

  openGames() {
    if(this.state.open === true) {
      this.setState({
        open: false
      });
    } else {
      this.setState({
        open: true
      });
    }   }

  render() {
    const open = this.state.open;
    return(
      <div class={ListStyles.list} style={{background: this.props.backgroundColor}}>
        <img className={ListStyles.img} src={this.props.img} />
        <div className={ListStyles.textBox}>
          <h2>{this.props.name}</h2>
          <span><b>{this.props.games}</b> Juegos</span>
        </div>
        <button className={open ? ListStyles.collapseUp : ListStyles.collapse} onClick={this.openGames}><img src={ArrowIcon} alt="" /></button>
        <button className={ListStyles.bin} onClick={this.openGames}><img src={BinIcon} alt="" /></button>
        <div style={{marginTop: '3em'}} className={open ? ListStyles.games : ListStyles.gamesNotOpen}>
          <Game name="League Of Legends" platform="PC" hours="2000" />
          <Game name="Borderlands" platform="XBOX 360" hours="50" />
          <span style={{display: 'block', height: '1em'}} />
          <AddButton backgroundColor="#fff" icon={PlusIconBlack} text="Añadir juego" textColor="#363636" type="game" />
        </div>
      </div>
    );   } }

class Game extends React.Component {   constructor(props) {
    super(props);   }

  render() {
    return(
      <div class={GameStyles.gameBox}>
        <h3>{this.props.name}</h3>
        <span><b>{this.props.hours}</b> Horas jugadas</span>
        <span><b>{this.props.platform}</b></span>
        <button className={GameStyles.bin} ><img src={BinIcon} alt="" /></button>
      </div>
    );   } }

class AddButtonBase extends React.Component {   constructor(props) {
    super(props);

    this.state = {
      open: false,
      listName: '',
      imgUrl: '',
      gameName: '',
      platform: '',
      hours: ''
    };

    this.openForm = this.openForm.bind(this);
    this.closeForm = this.closeForm.bind(this);
    this.openFormList = this.openFormList.bind(this);
    this.openFormGame = this.openFormGame.bind(this);   }

  submitList = (authUser) => {
    console.log(authUser)
    const { listName, imgUrl } = this.state;

    this.props.firebase.list(listName, JSON.parse(authUser).uid).set(
      {
        imgUrl,
      },
      { merge: true },
    ).then(() => this.closeList())
    .catch(error => console.log(error.message));   }

  submitGame = event => {
    //const { gameName, platform, hours } = this.state;

    console.log("SASNJKAB")   }

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

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

  openForm() {
    if(this.state.open === false) {
      this.setState({
        open: true
      });
    }   }

  closeForm() {
    if(this.state.open === true) {
      this.setState({
        open: false
      });
    }   }

  openFormList = () => (
    <ValidatorForm className={ButtonStyles.formList} ref="loginForm" onSubmit={this.submitList(localStorage.getItem("authUser"))}>
      <h3>Añadir Lista</h3>
      <span style={{display: 'block', width: '100%', height: '2px', background: '#fff', marginTop: '0.5em', marginBottom: '1.5em'}} />
      <TextInput
            style={{width: '26em'}}
            type="text"
            name="listName"
            title="Nombre de la lista"
            onChange={this.handleChangeList}
            value={this.state.listName}
            validators={['required', 'maxStringLength:20']}
            errorMessages={['Campo obligatorio', 'Se ha excedido el límite de caracteres']} /><br />
      <TextInput
            style={{width: '26em'}}
            type="text"
            name="imgUrl"
            title="Url para el icono de la lista"
            onChange={this.handleChangeList}
            value={this.state.imgUrl}
            validators={['required']}
            errorMessages={['Campo obligatorio']} /><br />
      <div style={{textAlign: 'right'}}>
        <button type="submit" className={ButtonStyles.createList}>Crear nueva lista</button>
        <button className={ButtonStyles.closeList} onClick={this.closeForm}>Cerrar</button>
      </div>
    </ValidatorForm>   )

  openFormGame = () => (
    <ValidatorForm className={ButtonStyles.formGame} ref="loginForm" onSubmit={this.submitGame()}>
      <h3>Añadir Juego</h3>
      <span style={{display: 'block', width: '100%', height: '2px', background: '#fff', marginTop: '0.5em', marginBottom: '1.5em'}} />
      <TextInput
            style={{width: '26em'}}
            type="text"
            name="gameName"
            title="Nombre del videojuego"
            onChange={this.handleChangeList}
            value={this.state.gameName}
            validators={['required', 'maxStringLength:20']}
            errorMessages={['Campo obligatorio', 'Se ha excedido el límite de caracteres']} /><br />
      <TextInput
            style={{width: '26em'}}
            type="text"
            name="platform"
            title="Plataforma"
            onChange={this.handleChangeList}
            value={this.state.platform}
            validators={['required', 'maxStringLength:10']}
            errorMessages={['Campo obligatorio', 'Se ha excedido el límite de caracteres']} /><br />
      <TextInput
            style={{width: '26em'}}
            type="text"
            name="hours"
            title="Horas jugadas"
            onChange={this.handleChangeList}
            value={this.state.hours}
            validators={['required', 'isNumber']}
            errorMessages={['Campo obligatorio', 'Este campo sólo admite números']} /><br />
      <div style={{textAlign: 'right'}}>
        <button type="submit" className={ButtonStyles.createGame}>Crear nueva lista</button>
        <button className={ButtonStyles.closeGame} onClick={this.closeForm}>Cerrar</button>
      </div>
    </ValidatorForm>   )

  render() {
    return(
      <div>
        <button onClick={this.openForm} className={ButtonStyles.button} style={{ background: this.props.backgroundColor, color: this.props.textColor }}><img src={this.props.icon} /> <span>{this.props.text}</span></button>
        {
          (this.state.open && (this.props.type === "list")) ? this.openFormList() : null
        }
        {
          this.state.open && this.props.type === "game" ? this.openFormGame() : null
        }
      </div>
    );   } }

const AddButton = withFirebase(AddButtonBase);

const condition = authUser => !!authUser;

export default withAuthorization(condition)(Games);

1 Ответ

1 голос
/ 14 июня 2019

Я полагаю, что ваша проблема в том, что вы вызываете свои методы отправки, когда назначаете их в качестве обратных вызовов.

Вы вызываете этот метод в скобках:

onSubmit={this.submitList(localStorage.getItem("authUser"))}

Здесь также:

onSubmit={this.submitGame()}

Сравните с вашими onclick обработчиками:

onClick={this.closeForm}

Есть несколько способовВы можете исправить это, например, удалив вызывающие скобки или заключив их в анонимные функции / замыкания, например:

onSubmit={()=> this.submitList(localStorage.getItem("authUser"))}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...