Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应状态存储&;输出重复值_Javascript_Reactjs_Firebase_State - Fatal编程技术网

Javascript 反应状态存储&;输出重复值

Javascript 反应状态存储&;输出重复值,javascript,reactjs,firebase,state,Javascript,Reactjs,Firebase,State,这里有一个小问题,我认为解决起来比较简单,但我不能完全理解。我还没有反应过来。我决定制作一个小的示例应用程序,它只需要从两个字段中获取输入,将它们保存到Firebase并在页面上输出这些值。就提交和检索数据而言,它工作得非常好,但当我单击“提交”按钮将数据添加到Firebase时,它似乎复制了存储在状态中的数据,并呈现了两次: 父组件: import React, { Component, Fragment } from 'react'; import firebase from '../..

这里有一个小问题,我认为解决起来比较简单,但我不能完全理解。我还没有反应过来。我决定制作一个小的示例应用程序,它只需要从两个字段中获取输入,将它们保存到Firebase并在页面上输出这些值。就提交和检索数据而言,它工作得非常好,但当我单击“提交”按钮将数据添加到Firebase时,它似乎复制了存储在状态中的数据,并呈现了两次:

父组件:

import React, { Component, Fragment } from 'react';

import firebase from '../../config/firebase';
import QuestFormField from './QuestFormField/QuestFormField';
import QuestFormSelection from './QuestFormSelection/QuestFormSelection';

import classes from './QuestForm.css';

class QuestForm extends Component {
    state = {
        value: '',
        points: 0,
        items: []
    }

    questHandler = e => {
        this.setState({
            value: e.target.value,
        });
    }

    pointsHandler = e => {
        this.setState({
            points: e.target.value,
        });
    }

    submitHandler = e => {
        e.preventDefault();
        const itemsRef = firebase.database().ref('quest');
        const items = {
            quest: this.state.value,
            points: this.state.points
        }
        itemsRef.push(items);
        this.setState({
            value: '',
            points: 0
        });
    }

    render () {
        return (
            <Fragment>
                <form className={classes.Form} onSubmit={this.submitHandler}>
                    <QuestFormField val='Quest' inputType='text' name='quest' value={this.state.value} changed={this.questHandler} />
                    <QuestFormField val='Points' inputType='number' name='points' value={this.state.points} changed={this.pointsHandler} />
                    <button>Away! To Firebase!</button>
                </form>
                <QuestFormSelection />
            </Fragment>
        );
    }

}

export default QuestForm;
import React,{Component,Fragment}来自'React';
从“../../config/firebase”导入firebase;
从“./QuestFormField/QuestFormField”导入QuestFormField;
从“/QuestFormSelection/QuestFormSelection”导入QuestFormSelection;
从“/QuestForm.css”导入类;
类QuestForm扩展组件{
状态={
值:“”,
分数:0,,
项目:[]
}
questHandler=e=>{
这是我的国家({
价值:即目标价值,
});
}
pointsHandler=e=>{
这是我的国家({
要点:即目标价值,
});
}
submitHandler=e=>{
e、 预防默认值();
const itemsRef=firebase.database().ref('quest');
常数项={
探索:这个。状态。价值,
点数:this.state.points
}
项目推送(项目);
这是我的国家({
值:“”,
分数:0
});
}
渲染(){
返回(
走开!去火力基地!
);
}
}
导出默认任务表单;
子组件(表单字段)

从“React”导入React;
从“/QuestFormField.css”导入类;
const QuestFormField=(道具)=>(
{props.val}
);
导出默认的QuestFormField;
子组件B(数据检索器/显示器)

import React,{Component,Fragment}来自'React';
从“../../config/firebase”导入firebase;
从“/QuestFormSelection.css”导入类;
类QuestFormSelection扩展了组件{
状态={
任务:[]
}
componentDidMount(){
const database=firebase.database();
常量任务=[];
database.ref('quest')。on('value',(快照)=>{
snapshot.forEach((childSnapshot)=>{
任务。推({
id:childSnapshot.key,
quest:childSnapshot.val().quest,
点:childSnapshot.val().points,
});
});
控制台日志(任务);
此.setState(()=>{
返回{
任务:任务
}
});
console.log(this.state.quests);
});
}
渲染(){
返回(
{this.state.quests.map(quest=>(
{quest.quest}

{quest.points}

))} ) } } 导出默认QuestFormSelection;
此处的行为示例:


任何指针都会有帮助:)

我自己还没有使用firebase,但下面的代码似乎正在设置一个侦听器,以便“quest”更改在每次更改发生时执行,但是您在db更改处理程序之外定义了
const quests=[]
。这意味着在第二次更改时,您将把快照中的所有内容都推送到相同的
任务
数组中,该数组可能已经添加了以前的快照。我相信您可以通过在listener函数中移动
quests
变量来解决这个问题,如下所示

componentDidMount() {
    const database = firebase.database();

    database.ref('quest').on('value', (snapshot) => {
        const quests = [];
        snapshot.forEach((childSnapshot) => {
            quests.push({
                id: childSnapshot.key,
                quest: childSnapshot.val().quest,
                points: childSnapshot.val().points,
            });
        });
        console.log(quests);
        this.setState(() => {
            return {
                quests: quests
            }
        });
        console.log(this.state.quests);
    });
}

您的
QuestFormSelection
组件中的控制台日志显示了什么?@Treycos最初,只显示存储在Firebase中的数据:但单击submit按钮会复制状态:You's right。这正是它所做的。它只是在顶部添加新的输入并重新渲染。谢谢你。
import React, { Component, Fragment } from 'react';

import firebase from '../../../config/firebase';

import classes from './QuestFormSelection.css';

class QuestFormSelection extends Component {
    state = {
        quests: []
    }

    componentDidMount() {
        const database = firebase.database();
        const quests = [];

        database.ref('quest').on('value', (snapshot) => {
            snapshot.forEach((childSnapshot) => {
                quests.push({
                    id: childSnapshot.key,
                    quest: childSnapshot.val().quest,
                    points: childSnapshot.val().points,
                });
            });
            console.log(quests);
            this.setState(() => {
                return {
                    quests: quests
                }
            });
            console.log(this.state.quests);
        });
    }

    render () {
        return (
            <section className='display-item'>
                <div className="wrapper">
                    {this.state.quests.map(quest => (
                        <div key={quest.key}>
                            <p>{quest.quest}</p>
                            <p>{quest.points}</p>
                        </div>
                    ))}
                </div>
            </section>
        )
    }
} 

export default QuestFormSelection;
componentDidMount() {
    const database = firebase.database();

    database.ref('quest').on('value', (snapshot) => {
        const quests = [];
        snapshot.forEach((childSnapshot) => {
            quests.push({
                id: childSnapshot.key,
                quest: childSnapshot.val().quest,
                points: childSnapshot.val().points,
            });
        });
        console.log(quests);
        this.setState(() => {
            return {
                quests: quests
            }
        });
        console.log(this.state.quests);
    });
}