返回HTML元素和组件
一个类组件的render()方法可以返回任何JSX,包括HTML元素和自定义React组件的混合。
在这个例子中,我们返回一个<Logo />组件(<Logo />是在其他地方定义的)
class Header extends React.Component {
render() {
return (
<div>
<Logo />
<h1>Hello World</h1>
</div>
);
}
}
React组件export
常见的做法是将每个React组件放在自己的文件中,然后利用export将其导出,然后在其他需要的地方将其导入。这种文件组织有助于使组件可重复使用。
在这个例子中,我们可能有两个文件,一个是App.js,它是我们应用程序的顶级组件,另一个是Clock.js,一个子组件。
// Clock.js
import React from 'react';
export class Clock extends React.Component {
render() {
// ...
}
}
// App.js
import React from 'react';
import { Clock } from './Clock';
class App extends React.Component {
render() {
return (
<div>
<h1>What time is it?</h1>
<Clock />
</div>
);
}
}
this.props
React类组件可以通过this.props对象访问它们的props。
在下面的示例代码中,我们看到<Hello>组件被渲染时有一个firstName。它是在组件的render()方法中用this.props.firstName访问的。
这应该会呈现出文本 "Hi there, Kim!"
class Hello extends React.Component {
render() {
return <h1>Hi there, {this.props.firstName}!</h1>;
}
}
ReactDOM.render(<Hello firstName="Kim" />, document.getElementById('app'));
defaultProps
一个React组件的defaultProps对象包含默认值,在没有传递prop的情况下使用。如果一个prop没有被传递给一个组件,那么它将被替换成defaultProps对象中的值。
在示例代码中,defaultProps的设置是为了在没有设置的情况下,配置文件有一个备用的配置文件图片。
在下面的代码中,<MyFriends>组件应该渲染两个Profile:一个名为Jane Doe的使用设定的简介图片,一个名为John Smith的使用默认的简介图片。
class Profile extends React.Component {
render() {
return (
<div>
<img src={this.props.profilePictureSrc} alt="" />
<h2>{this.props.name}</h2>
</div>
);
}
}
Profile.defaultProps = {
profilePictureSrc: 'https://example.com/no-profile-picture.jpg',
};
class MyFriends extends React.Component {
render() {
return (
<div>
<h1>My friends</h1>
<Profile
name="Jane Doe"
profilePictureSrc="https://example.com/jane-doe.jpg"
/>
<Profile name="John Smith" />
</div>
);
}
}
Prop
组件可以向其他组件传递信息。当一个组件向另一个组件传递信息时,它是通过Prop来传递一个或多个属性的。
示例代码演示了属性在props中的使用。SpaceShip是组件,ride是属性。SpaceShip组件将在其props中接收ride。
<SpaceShip ride="Millennium Falcon" />
this.props.children
每个组件的props对象都有一个名为children的属性。使用this.props.children将返回一个组件的开头和结尾的JSX标签之间的一切。
render() {
console.log(this.props.children)
};
绑定 this
在React Class组件中,常见的是在render()方法中向元素传递事件处理函数(event handler function)。如果这些方法更新了组件的状态,this必须被绑定,以便这些method能够正确地更新整个组件的状态。
在下面的示例代码中,我们绑定了this.changeName(),这样我们的event handler程序就能发挥作用。
class MyName extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'Jane Doe' };
this.changeName = this.changeName.bind(this);
}
changeName(newName) {
this.setState({ name: newName });
}
render() {
return (
<h1>My name is {this.state.name}</h1>
<NameChanger handleChange={this.changeName} />
)
}
}
在构造函数中调用super()
React Class组件应该在其constructor函数中调用super(props),以便正确设置其this.props对象。
// WRONG! 这样不对!
class BadComponent extends React.Component {
constructor() {
this.state = { favoriteColor: 'green' };
}
// ...
}
// RIGHT! 这样才对!
class GoodComponent extends React.Component {
constructor(props) {
super(props);
this.state = { favoriteColor: 'green' };
}
// ...
}
this.setState()
React Class组件可以通过this.setState()来改变它们的状态。应该始终使用this.setState()而不是直接修改this.state对象。
this.setState()接收一个对象,并将其与组件的当前状态合并。如果在当前状态下有不属于该对象的属性,那么这些属性就不会改变。
在下面的示例代码中,我们看到this.setState()被用来将Flavor组件的状态从 "Apple "更新为 "Banana"。
class Flavor extends React.Component {
constructor(props) {
super(props);
this.state = {
favorite: 'Apple',
};
}
render() {
return (
<button
onClick={(event) => {
event.preventDefault();
this.setState({ favorite: 'Banana' });
}}
>
No, my favorite is vanilla
</button>
);
}
}
组件中的动态数据
React组件可以从props接收动态信息,也可以用state来设置自己的动态数据。Props是由父级组件传递下来的,而state是由组件本身创建和维护的。
在这个例子中,你可以看到this.state在constructor函数中设置,在render()中使用,并通过this.setState()更新。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { showPassword: false };
}
render() {
let text;
if (this.state.showPassword) {
text = `The password is ${this.props.password}`;
} else {
text = 'The password is a secret';
}
return (
<div>
<p>{text}</p>
<button
onClick={(event) => {
event.preventDefault();
this.setState((oldState) => ({
showPassword: !oldState.showPassword,
}));
}}
>
Toggle password
</button>
</div>
);
}
}
构造函数中的组件状态
React Class组件将它的state存储为一个JavaScript对象。这个对象在组件的constructor函数中被初始化。
在这个例子中,该组件将其state存储在this.state中。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
favoriteColor: 'green',
favoriteMusic: 'Bluegrass',
};
}
render() {
// ...
}
}
渲染时不要改变状态
当你更新一个React组件的state时,它将自动重新渲染。这意味着你不应该在渲染函数(render)中更新状态,因为这将导致无限循环。
在这个例子中,我们展示了一些不好的代码,在其render()方法中调用this.setState()。
class BadComponent extends React.Component {
constructor(props) {
super(props);
this.count = 0;
}
render() {
// 不要写这个代码 这样不好
this.setState({ count: this.state.count + 1 });
return <div>The count is {this.state.count}</div>;
}
}
参考资料:Codecademy