新的反应,单击按钮时我很难尝试增加人的年龄。
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;
我只是对应该如何工作感到困惑。没有错误,但是单击该按钮时没有任何反应。
答案 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
答案 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.
/>
));
)
}
更新一个人的年龄变得稍微复杂一些,但是仍然相当简单。我们需要执行以下操作的函数:
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
希望这会有所帮助。