单击按钮时,无法增加年龄

时间:2020-08-31 19:16:34

标签: javascript reactjs

新的反应,单击按钮时我很难尝试增加人的年龄。

EventComp.js代码:

import React, { Component } from 'react';

class EventComp extends Component{
constructor(props) {
    super(props);
    this.state = {
        clicks: 0,
        show: true,
    };
}
 IncrementItem = () => {
     this.setState({clicks: this.state.clicks + 1});
 }

render(){
    return(
        <div>
        <div class = "person">
        <h1 class="person_h1">
        {this.props.LastName}, 
        {this.props.FirstName}</h1>
        <p>Age: {this.props.Age}</p>
        </div>
        
     <button onClick = {this.IncrementItem}>Celebrate</button>
      
</div>
    
    )
  }
}
export default EventComp;

App.js代码:

import React from 'react';
import EventComp from './components/EventComp';
import './App.css';

function App() {
  return (
    <div class ="main">
      <div>
        <EventComp FirstName="Jane " 
        LastName=" Doe " Age = {45}/>
      </div>

      <div>
        <EventComp FirstName = "Joe " LastName = " Doe " Age={88}/>
      </div>
      <div>

      </div>
    </div>
  );
}

export default App;

我只是对应该如何工作感到困惑。没有错误,但是单击该按钮时没有任何反应。

2 个答案:

答案 0 :(得分:0)

您没有在IncrementItem函数中更新年龄。相反,您要更新点击次数。您没有看到任何事件的原因是,点击没有在任何地方呈现。如果添加日志语句并单击日志,则会看到它正在更新。

但是,如果您对增加年龄感兴趣,则首先需要将状态添加到年龄:

this.state = {
    clicks: 0,
    show: true,
    age: this.props.Age
};

请注意,将来道具通常是小写的,我建议改为以“年龄”形式传递道具。

您应该在增量功能中执行的第二件事是更新年龄而不是点击。如果添加控制台语句,您将看到该函数实际上已被调用。您还会注意到,年龄在增加,而不是点击,这是因为我们对这种状态感兴趣。还应该在定义状态以保留上下文的地方定义该函数。

注意:react中的函数是小写的,组件是大写的。函数还倾向于使用“句柄”命名约定,在这种情况下,函数应命名为“ handleIncrementAge”

 IncrementItem = () => {
   this.setState({clicks: this.state.clicks + 1,
     age: this.state.age + 1
    });

 }

最后,在渲染中,因为似乎您对更新状态感兴趣,所以您希望显示该状态。

<p>Increment Age: {this.state.age}</p>

* class属性应该更改为className,因为class是React中的保留关键字。不这样做会导致您的样式无法呈现。

我已在CodeSandbox中附加了您的代码和建议的更改:Code Sandbox

Updating State with React Class Components

答案 1 :(得分:0)

...很难增加年龄...

执行此类操作的一种常见方法是,将父组件和子组件(App和EventComp)的职责分开,以使父组件管理状态(保持年龄的记录)和子组件(EventComp)是一个“哑巴”组件,仅呈现给定的任何信息。

您已经通过传递“人”信息作为道具来完成大部分工作:

<EventComp FirstName="Joe" LastName="Doe" Age={88} /> // ?

如果您在App中将年龄作为状态进行跟踪,则更改“年龄”将重新呈现,并将更新的年龄传递给EventComp:

function App () {
  // create a state variable and a setter function for updating its value
  const [age, setAge] = React.useState(88);

  // pass age as a prop:
  return (
    <EventComp FirstName="Joe" LastName="Doe" Age={age} />
  );
}

年龄如何更新?通过调用setAge。这是上面相同的示例,只是添加了一个使age递增的按钮:

function App () {
  const [age, setAge] = React.useState(88);

  return (
    <div>
      <button onClick={() => setAge(age + 1)}>Increment Age</button>
      <EventComp FirstName="Joe" LastName="Doe" Age={age} />
    </div>
  );
}

每次单击都将触发重新渲染以显示新年龄。

但是您希望EventComp中的按钮不在App中。我们如何将EventComp中的按钮连接到App中的状态?通过将更新功能作为道具:

function App () {
  const [age, setAge] = React.useState(88);

  return (
      <EventComp
        FirstName="Joe"
        LastName="Doe"
        Age={age}
        onIncrementAge={() => setAge(age + 1)} // <= pass the age incrementing function as a prop
      />
  );
}

function EventComp (props) {
  return (
    <div>
      <div class = "person">
        <h1 class="person_h1">
          {props.LastName}, 
          {props.FirstName}</h1>
          <p>Age: {props.Age}</p>
      </div>
        
      <button onClick={props.onIncrementAge}>  // <= onClick calls the function provided via props
        Celebrate
      </button>
    </div>
  )
}

使用这种模式,只有一个关于年龄值的事实来源,EventComp不需要知道或关心年龄的来源。


将其扩展为可以容纳多个人:

以上示例演示了基本模式,但没有满足处理多个人的需要。假设您有一个人名单:

const people = [
  {
    firstName: 'Jane',
    lastName: 'Doe',
    age: 45
  },
  {
    firstName: 'Joe',
    lastName: 'Doe',
    age: 88
  },
]

您可以遍历此列表,为每个人渲染一个组件:

function App () {
  // initial state with 2 people
  const [people, setPeople] = React.useState([
    { firstName: 'Jane', lastName: 'Doe', age: 45 },
    { firstName: 'Joe', lastName: 'Doe', age: 88 },
  ]);

  return (
    people.map((person) => ( // render an EventComp for each person
      <EventComp
        FirstName={person.firstName}
        LastName={person.lastName}
        age={person.age}
        key={person.firstName} // key is a react thing. ignore for now.
      />
    ));
  )
}

更新一个人的年龄变得稍微复杂一些,但是仍然相当简单。我们需要执行以下操作的函数:

  1. 按索引查找人员(他们在列表中的位置)
  2. 更新年龄
  3. 使用新信息更新状态
const incrementAge = index => {
  const person = people[index];
  person.age += 1;
  setPeople([...people]);
}

将此新函数传递给EventComp,您就完成了。

function App () {
  // initial state with 2 people
  const [people, setPeople] = React.useState([
    { firstName: 'Jane', lastName: 'Doe', age: 45 },
    { firstName: 'Joe', lastName: 'Doe', age: 88 },
  ]);

  const incrementAge = index => {
    const person = people[index];
    person.age += 1;
    setPeople([...people]); // spread to a new array so react recognizes it as new
  }

  return (
    people.map((person, index) => ( // render an EventComp for each person
      <EventComp
        FirstName={person.firstName}
        LastName={person.lastName}
        age={person.age}
        onIncrementAge={() => incrementAge(index)} // <= indicate which person via index
        key={person.firstName} // key is a react thing. ignore for now.
      />
    ));
  )
}

请注意,我们已将index参数添加到地图调用中:

people.map((person, index) => {

我们在调用点击处理程序时正在使用它:

onIncrementAge={() => incrementAge(index)}

Voila。


您还可以将人物作为单个道具传递:

<EventComp
  person={person}
  onIncrementAge={() => incrementAge(index)}
/>

// use props.person.FirstName, etc. in EventComp

希望这会有所帮助。