无法更新反应应用程序的状态

时间:2018-07-12 10:43:29

标签: javascript reactjs

我正在学习React课程,并尝试更新App中的状态(配置文件)。

当我单击按钮时,我可以看到新的配置文件几毫秒,然后它将返回到原始两个配置文件的列表。

我哪部分弄错了?谢谢。

这是显示一些配置文件和一个添加新配置文件的按钮的应用程序。

// app.js

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

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      profiles: [
        {name: 'Joan', age: 30, bio: 'enjoys swimming and biking', hobbies: ['swimming', 'biking']},
        {name: 'John', age: 40, bio: 'enjoys long walks on the beach', hobbies: ['gardening', 'TV']}
      ]
    };
  }


  addUser = (newProfile) => {
    this.setState({
      profiles: this.state.profiles.concat([newProfile])
    })
  };

  render() {
    let profiles = this.state.profiles.map(profile => {
      return (
        <Profile
          name={profile.name}
          age={profile.age}
          bio={profile.bio}
          hobbies={profile.hobbies}
        />
      )
    });

    return <div className="App">
      {profiles}
      <AddProfile addUser={this.addUser}/>
    </div>;
  }
}

export default App;

另一个用于处理添加配置文件的类。重复很多,但是大多数重复一次地针对每个配置文件中的四个属性执行相同的操作。

// AddProfile.js

import React from "react";

class AddProfile extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'your name', // default
      age: '',
      bio: '',
      hobbies: ''
    }
  }

  handleName = (e) => {
    this.setState({
      name: e.target.value
    })
  };

  handleAge = (e) => {
    this.setState({
      age: e.target.value
    })
  };

  handleBio = (e) => {
    this.setState({
      bio: e.target.value
    })
  };

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

  handleClick = (e) => {
    let newProfile = {
      name: this.state.name,
      age: this.state.age,
      bio: this.state.bio,
      hobbies: [this.state.hobbies]
    };
    this.props.addUser(newProfile);
  };

  render() {
    return (
      <div>
        <form>
          <p>Add a new profile</p>
          <input onChange={this.handleName} id="name" value={this.state.name} />
          <br/>
          <input onChange={this.handleAge} id="age" value={this.state.age} />
          <br/>
          <input onChange={this.handleBio} id="bio" value={this.state.bio} />
          <br/>
          <input onChange={this.handleHobbies} id="hobbies" value={this.state.hobbies} />
          <br/>
          <button onClick={this.handleClick}>Add New Profile</button>
        </form>
      </div>
    )
  }
}

export default AddProfile;

个人资料呈现组件的隔离功能。

// Profile.js

import React from 'react';

let Profile = props => (
  <div>
    <h3>{props.name}</h3>
    <p>
      {props.name} is {props.age} and {props.bio}
    </p>
    <h4>Hobbies:</h4>
    <ul>
      {props.hobbies.map(hobby=><li>{hobby}</li>)}
    </ul>
  </div>
);

export default Profile;

现在挠了一下头...

3 个答案:

答案 0 :(得分:1)

问题是您没有阻止form的默认浏览器行为,即重新加载浏览器。

在给preventDefault的事件上使用handleClick,它将按预期运行。

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

  let newProfile = {
    name: this.state.name,
    age: this.state.age,
    bio: this.state.bio,
    hobbies: [this.state.hobbies]
  };

  this.props.addUser(newProfile);
};

答案 1 :(得分:0)

我认为这是因为您没有在个人档案组件上添加密钥:React Keys

  

键可帮助React识别哪些项目已更改,添加或删除。

尝试一下:

  render() {
  let profiles = this.state.profiles.map((profile, index) => {
  return (
    <Profile
      key={index}
      name={profile.name}
      age={profile.age}
      bio={profile.bio}
      hobbies={profile.hobbies}
    />
  )
});

return <div className="App">
  {profiles}
  <AddProfile addUser={this.addUser}/>
</div>;
  }
}

PS:您不需要在Profile组件的道具中具有“键”,它仅由React使用。

答案 2 :(得分:-1)

首先,不要更改状态值,因此请替换功能:

addUser = (newProfile) => {
    this.setState(prevState=>({
      profiles: [...prevState.profiles, newProfile ]
    }))
  };

Array.prototype.concat()对数组进行突变。 约setStatehttps://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b