React组件会自动呈现给它的初始状态

时间:2018-01-18 15:31:59

标签: reactjs

我正在做一个简单的反应测试应用程序。

什么是应用程序:它显示项目名称,并可选择添加新项目。每个项目都有标题和类别。

这就是它的外观

enter image description here

问题:当我尝试通过输入标题然后单击“提交”按钮添加新项目时,新项目名称会在项目中显示几分钟,然后消失。项目列表返回初始状态,即三个项目(如下所示)

这是代码

App.js

import React, { Component } from 'react';

import './App.css';
import Projects from "./Components/Projects"
import AddProjects from './Components/AddProject'

class App extends Component {
  constructor(){
    super();
    this.state = {
      projects:[]
    }
  }

  componentWillMount(){
      this.setState({projects:[
          {
              title: "Trigger",
              category: "Web App"
          },
          {
              title: "Trigger",
              category: "Web App"
          },
          {
              title: "Trigger",
              category: "Web App"
          }
      ]})
  }

  handleAddProject(project){
      let projects = this.state.projects;
      projects.push(project)
      this.setState({projects:projects})
      console.log(this.state.projects)
  }

  render() {
    return (
      <div className="App">
        My Project
          <AddProjects addProject={this.handleAddProject.bind(this)}/>
          <Projects projects={this.state.projects}/>
      </div>
    );
  }
}

export default App;

Projects.js

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


class Projects extends Component {

    render() {
        let projectItems
        if(this.props.projects){
            projectItems = this.props.projects.map(project =>{
                return (
                    <Projectitem project={project}/>
                );
            })
        }
        else{
            console.log("hello")
        }

        return (
            <div>
                This is a list of objects
                {projectItems}
            </div>
        );
    }
}

export default Projects

ProjectItem.js

import React, { Component } from 'react';


class ProjectItem extends Component {
    render() {
        return (

                <li>
                    {this.props.project.title}:{this.props.project.category}
                </li>

        );
    }
}

export default ProjectItem

AddProject.js

import React, { Component } from 'react';


var categories = ["Web dev", "Mobile dev", "websiite"]

class AddProject extends Component {
    constructor(){
        super();
        this.state = {
            newProject:{}
        }
    }


    handleSubmit(){
        this.setState({newProject:{
            title:this.refs.title.value,
            category:this.refs.category.value
        }}, function () {
            this.props.addProject(this.state.newProject)
        })
    }
    render() {
        var categoryOptions = categories.map(category=>{
            return <option key={category} value={category}>{category}</option>
        })
        return (
            <div>
                Add Project <br/>
                <form onSubmit={this.handleSubmit.bind(this)}>
                    <div>
                        <label>title</label><br/>
                        <input type="text" ref="title"/>
                    </div>
                    <div>
                        <label>Category</label><br/>
                        <select ref="category">
                            {categoryOptions}
                        </select>
                    </div>
                    <input type="submit" value="Submit"/>
                </form>
            </div>

        );
    }
}

export default AddProject

3 个答案:

答案 0 :(得分:2)

event.preventDefault()添加到您的handleSubmit()方法

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
}

如果没有它,您的页面将刷新(就像提交表单时默认情况一样)

答案 1 :(得分:2)

你直接编辑国家,这在React中是一个很大的禁忌。

将处理程序功能更改为以下内容:

handleAddProject(project){
  this.setState((prevState) => {
    return { projects: [...prevState.projects, project] }
  })
}

setState功能可以使用&#39;回调&#39;来接收其呼叫前的状态,并允许您修改它。重要的部分是直接改变状态(正如你的projects.push(project)行所做的那样)。

其他选项,更像是你正在尝试做的事情,就是在变异之前复制当前状态:

handleAddProject(project){
  let projects = this.state.projects.slice(); // notice the slice here will return
                                              // a copy of 'projects', and then
                                              // you modify it
  projects.push(project)
  this.setState({projects:projects})
  console.log(this.state.projects)
}

另外,请注意,setState被称为异步,因此console.log(this.state.projects)调用可能会显示旧状态,因为setState可能不是叫了。

答案 2 :(得分:0)

如果您使用输入类型=&#34;提交&#34;您正在使用Form tag来向网络服务器提交信息。它将始终重新加载页面和初始everithig作为第一次加载。如果你像@Galupuf一样,它会起作用  因为event.preventDefault();将不允许浏览器重新加载,并且它不会在首次加载时初始化。

我的回答是,如果您没有向任何服务器发送任何数据或者正在使用服务器,请更改div的表单标记输入类型=&#34;提交&#34;为<button onClick={()=>this.handleSubmit()}>Send</button>

 <div>
                <div>
                    <label>title</label><br/>
                    <input type="text" ref="title"/>
                </div>
                <div>
                    <label>Category</label><br/>
                    <select ref="category">
                        {categoryOptions}
                    </select>
                </div>
                  <button onClick={()=>this.handleSubmit()}>Submit</button>
            </div>

其他建议工作像@cfraser这样的状态的修改值建议你将拥有不可变数据